Skip to content

Commit 713a236

Browse files
UserData as first class resource (#6202)
This PR introduces a new feature to make userdata as a first class resource much like existing SSH keys. Detailed feature specification document: https://cwiki.apache.org/confluence/display/CLOUDSTACK/Userdata+as+a+first+class+resource
1 parent c83dee5 commit 713a236

File tree

94 files changed

+6480
-177
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

94 files changed

+6480
-177
lines changed

api/src/main/java/com/cloud/event/EventTypes.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,8 @@ public class EventTypes {
101101
public static final String EVENT_VM_DYNAMIC_SCALE = "VM.DYNAMIC.SCALE";
102102
public static final String EVENT_VM_RESETPASSWORD = "VM.RESETPASSWORD";
103103
public static final String EVENT_VM_RESETSSHKEY = "VM.RESETSSHKEY";
104+
105+
public static final String EVENT_VM_RESETUSERDATA = "VM.RESETUSERDATA";
104106
public static final String EVENT_VM_MIGRATE = "VM.MIGRATE";
105107
public static final String EVENT_VM_MOVE = "VM.MOVE";
106108
public static final String EVENT_VM_RESTORE = "VM.RESTORE";
@@ -235,6 +237,9 @@ public class EventTypes {
235237
//registering SSH keypair events
236238
public static final String EVENT_REGISTER_SSH_KEYPAIR = "REGISTER.SSH.KEYPAIR";
237239

240+
//registering userdata events
241+
public static final String EVENT_REGISTER_USER_DATA = "REGISTER.USER.DATA";
242+
238243
//register for user API and secret keys
239244
public static final String EVENT_REGISTER_FOR_SECRET_API_KEY = "REGISTER.USER.KEY";
240245

api/src/main/java/com/cloud/network/NetworkModel.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
package com.cloud.network;
1919

2020
import java.util.ArrayList;
21+
import java.util.Arrays;
2122
import java.util.List;
2223
import java.util.Map;
2324
import java.util.Set;
@@ -85,6 +86,9 @@ public interface NetworkModel {
8586
.put(HYPERVISOR_HOST_NAME_FILE, HYPERVISOR_HOST_NAME_FILE)
8687
.build();
8788

89+
List<String> metadataFileNames = new ArrayList<>(Arrays.asList(SERVICE_OFFERING_FILE, AVAILABILITY_ZONE_FILE, LOCAL_HOSTNAME_FILE, LOCAL_IPV4_FILE, PUBLIC_HOSTNAME_FILE, PUBLIC_IPV4_FILE,
90+
INSTANCE_ID_FILE, VM_ID_FILE, PUBLIC_KEYS_FILE, CLOUD_IDENTIFIER_FILE, HYPERVISOR_HOST_NAME_FILE));
91+
8892
static final ConfigKey<Integer> MACIdentifier = new ConfigKey<Integer>("Advanced",Integer.class, "mac.identifier", "0",
8993
"This value will be used while generating the mac addresses for isolated and shared networks. The hexadecimal equivalent value will be present at the 2nd octet of the mac address. Default value is null which means this feature is disabled.Its scope is global.", true, ConfigKey.Scope.Global);
9094

@@ -325,7 +329,7 @@ public interface NetworkModel {
325329

326330
boolean getNetworkEgressDefaultPolicy(Long networkId);
327331

328-
List<String[]> generateVmData(String userData, String serviceOffering, long datacenterId,
332+
List<String[]> generateVmData(String userData, String userDataDetails, String serviceOffering, long datacenterId,
329333
String vmName, String vmHostName, long vmId, String vmUuid, String guestIpAddress, String publicKey, String password, Boolean isWindows, String hostname);
330334

331335
String getValidNetworkCidr(Network guestNetwork);

api/src/main/java/com/cloud/server/ManagementService.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import java.util.List;
2121
import java.util.Map;
2222

23+
import com.cloud.user.UserData;
2324
import org.apache.cloudstack.api.command.admin.cluster.ListClustersCmd;
2425
import org.apache.cloudstack.api.command.admin.config.ListCfgsByCmd;
2526
import org.apache.cloudstack.api.command.admin.config.UpdateHypervisorCapabilitiesCmd;
@@ -56,6 +57,9 @@
5657
import org.apache.cloudstack.api.command.user.ssh.DeleteSSHKeyPairCmd;
5758
import org.apache.cloudstack.api.command.user.ssh.ListSSHKeyPairsCmd;
5859
import org.apache.cloudstack.api.command.user.ssh.RegisterSSHKeyPairCmd;
60+
import org.apache.cloudstack.api.command.user.userdata.DeleteUserDataCmd;
61+
import org.apache.cloudstack.api.command.user.userdata.ListUserDataCmd;
62+
import org.apache.cloudstack.api.command.user.userdata.RegisterUserDataCmd;
5963
import org.apache.cloudstack.api.command.user.vm.GetVMPasswordCmd;
6064
import org.apache.cloudstack.api.command.user.vmgroup.UpdateVMGroupCmd;
6165
import org.apache.cloudstack.config.Configuration;
@@ -333,6 +337,33 @@ public interface ManagementService {
333337
*/
334338
String generateRandomPassword();
335339

340+
/**
341+
* Search registered userdatas for the logged in user.
342+
*
343+
* @param cmd
344+
* The api command class.
345+
* @return The list of userdatas found.
346+
*/
347+
Pair<List<? extends UserData>, Integer> listUserDatas(ListUserDataCmd cmd);
348+
349+
/**
350+
* Registers a userdata.
351+
*
352+
* @param cmd
353+
* The api command class.
354+
* @return A VO with the registered userdata.
355+
*/
356+
UserData registerUserData(RegisterUserDataCmd cmd);
357+
358+
/**
359+
* Deletes a userdata.
360+
*
361+
* @param cmd
362+
* The api command class.
363+
* @return True on success. False otherwise.
364+
*/
365+
boolean deleteUserData(DeleteUserDataCmd cmd);
366+
336367
/**
337368
* Search registered key pairs for the logged in user.
338369
*

api/src/main/java/com/cloud/template/TemplateApiService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import com.cloud.exception.StorageUnavailableException;
4141
import com.cloud.user.Account;
4242
import com.cloud.utils.exception.CloudRuntimeException;
43+
import org.apache.cloudstack.api.command.user.userdata.LinkUserDataToTemplateCmd;
4344
import org.apache.cloudstack.api.response.GetUploadParamsResponse;
4445

4546
public interface TemplateApiService {
@@ -56,6 +57,8 @@ public interface TemplateApiService {
5657

5758
VirtualMachineTemplate prepareTemplate(long templateId, long zoneId, Long storageId);
5859

60+
61+
5962
boolean detachIso(long vmId, boolean forced);
6063

6164
boolean attachIso(long isoId, long vmId, boolean forced);
@@ -106,4 +109,6 @@ public interface TemplateApiService {
106109
VirtualMachineTemplate updateTemplate(UpdateIsoCmd cmd);
107110

108111
VirtualMachineTemplate updateTemplate(UpdateTemplateCmd cmd);
112+
113+
VirtualMachineTemplate linkUserDataToTemplate(LinkUserDataToTemplateCmd cmd);
109114
}

api/src/main/java/com/cloud/template/VirtualMachineTemplate.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import java.util.Date;
2020
import java.util.Map;
2121

22+
import com.cloud.user.UserData;
2223
import org.apache.cloudstack.acl.ControlledEntity;
2324
import org.apache.cloudstack.api.Identity;
2425
import org.apache.cloudstack.api.InternalIdentity;
@@ -142,4 +143,9 @@ public enum TemplateFilter {
142143
Date getUpdated();
143144

144145
boolean isDeployAsIs();
146+
147+
Long getUserDataId();
148+
149+
UserData.UserDataOverridePolicy getUserDataOverridePolicy();
150+
145151
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
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+
package com.cloud.user;
18+
19+
import org.apache.cloudstack.acl.ControlledEntity;
20+
import org.apache.cloudstack.api.Identity;
21+
import org.apache.cloudstack.api.InternalIdentity;
22+
23+
public interface UserData extends ControlledEntity, InternalIdentity, Identity {
24+
25+
public enum UserDataOverridePolicy {
26+
ALLOWOVERRIDE, APPEND, DENYOVERRIDE
27+
}
28+
29+
String getUserData();
30+
31+
String getParams();
32+
}

api/src/main/java/com/cloud/uservm/UserVm.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,14 @@ public interface UserVm extends VirtualMachine, ControlledEntity {
3535

3636
void setUserData(String userData);
3737

38+
void setUserDataId(Long userDataId);
39+
40+
Long getUserDataId();
41+
42+
void setUserDataDetails(String userDataDetails);
43+
44+
String getUserDataDetails();
45+
3846
String getDetail(String name);
3947

4048
void setAccountId(long accountId);

api/src/main/java/com/cloud/vm/UserVmService.java

Lines changed: 36 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
import org.apache.cloudstack.api.command.user.vm.RemoveNicFromVMCmd;
3030
import org.apache.cloudstack.api.command.user.vm.ResetVMPasswordCmd;
3131
import org.apache.cloudstack.api.command.user.vm.ResetVMSSHKeyCmd;
32+
import org.apache.cloudstack.api.command.user.vm.ResetVMUserDataCmd;
3233
import org.apache.cloudstack.api.command.user.vm.RestoreVMCmd;
3334
import org.apache.cloudstack.api.command.user.vm.ScaleVMCmd;
3435
import org.apache.cloudstack.api.command.user.vm.StartVMCmd;
@@ -103,6 +104,8 @@ public interface UserVmService {
103104
*/
104105
UserVm resetVMSSHKey(ResetVMSSHKeyCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;
105106

107+
UserVm resetVMUserData(ResetVMUserDataCmd cmd) throws ResourceUnavailableException, InsufficientCapacityException;
108+
106109
UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, ExecutionException, ConcurrentOperationException, ResourceUnavailableException,
107110
InsufficientCapacityException, ResourceAllocationException;
108111

@@ -146,6 +149,12 @@ UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, E
146149
*
147150
*
148151
*
152+
* @param sshKeyPair
153+
* - name of the ssh key pair used to login to the virtual
154+
* machine
155+
* @param cpuSpeed
156+
* @param memory
157+
* @param cpuNumber
149158
* @param zone
150159
* - availability zone for the virtual machine
151160
* @param serviceOffering
@@ -181,29 +190,25 @@ UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, E
181190
* base64 encoded before adding it to the request. Currently only
182191
* HTTP GET is supported. Using HTTP GET (via querystring), you
183192
* can send up to 2KB of data after base64 encoding
184-
* @param sshKeyPair
185-
* - name of the ssh key pair used to login to the virtual
186-
* machine
193+
* @param userDataId
194+
* @param userDataDetails
187195
* @param requestedIps
188196
* TODO
189197
* @param defaultIp
190198
* TODO
191199
* @param displayVm
192200
* - Boolean flag whether to the display the vm to the end user or not
193201
* @param affinityGroupIdList
194-
* @param cpuSpeed
195-
* @param memory
196-
* @param cpuNumber
197202
* @param customId
198203
* @param dhcpOptionMap
199204
* - Maps the dhcp option code and the dhcp value to the network uuid
200-
* @return UserVm object if successful.
201205
* @param dataDiskTemplateToDiskOfferingMap
202206
* - Datadisk template to Disk offering Map
203207
* an optional parameter that creates additional data disks for the virtual machine
204208
* For each of the templates in the map, a data disk will be created from the corresponding
205209
* disk offering obtained from the map
206210
*
211+
* @return UserVm object if successful.
207212
* @throws InsufficientCapacityException
208213
* if there is insufficient capacity to deploy the VM.
209214
* @throws ConcurrentOperationException
@@ -214,11 +219,11 @@ UserVm startVirtualMachine(StartVMCmd cmd) throws StorageUnavailableException, E
214219
* available.
215220
*/
216221
UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> securityGroupIdList,
217-
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
218-
String userData, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
219-
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
220-
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
221-
Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId) throws InsufficientCapacityException,
222+
Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod,
223+
String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIp, Boolean displayVm, String keyboard,
224+
List<Long> affinityGroupIdList, Map<String, String> customParameter, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
225+
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
226+
Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId) throws InsufficientCapacityException,
222227
ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
223228

224229
/**
@@ -227,6 +232,7 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
227232
*
228233
*
229234
*
235+
* @param type
230236
* @param zone
231237
* - availability zone for the virtual machine
232238
* @param serviceOffering
@@ -264,6 +270,8 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
264270
* base64 encoded before adding it to the request. Currently only
265271
* HTTP GET is supported. Using HTTP GET (via querystring), you
266272
* can send up to 2KB of data after base64 encoding
273+
* @param userDataId
274+
* @param userDataDetails
267275
* @param requestedIps
268276
* TODO
269277
* @param defaultIps
@@ -279,7 +287,6 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
279287
* an optional parameter that creates additional data disks for the virtual machine
280288
* For each of the templates in the map, a data disk will be created from the corresponding
281289
* disk offering obtained from the map
282-
* @param type
283290
* @return UserVm object if successful.
284291
*
285292
* @throws InsufficientCapacityException
@@ -292,17 +299,23 @@ UserVm createBasicSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering s
292299
* available.
293300
*/
294301
UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList,
295-
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
296-
HTTPMethod httpmethod, String userData, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
297-
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
298-
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, String vmType) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
302+
List<Long> securityGroupIdList, Account owner, String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor,
303+
HTTPMethod httpmethod, String userData, Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard,
304+
List<Long> affinityGroupIdList, Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap,
305+
Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap, Map<String, String> userVmOVFProperties, boolean dynamicScalingEnabled, Long overrideDiskOfferingId, String vmType) throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
299306

300307
/**
301308
* Creates a User VM in Advanced Zone (Security Group feature is disabled)
302309
* in the database and returns the VM to the caller.
303310
*
304311
*
305312
*
313+
* @param sshKeyPair
314+
* - name of the ssh key pair used to login to the virtual
315+
* machine
316+
* @param cpuSpeed
317+
* @param memory
318+
* @param cpuNumber
306319
* @param zone
307320
* - availability zone for the virtual machine
308321
* @param serviceOffering
@@ -337,19 +350,15 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin
337350
* base64 encoded before adding it to the request. Currently only
338351
* HTTP GET is supported. Using HTTP GET (via querystring), you
339352
* can send up to 2KB of data after base64 encoding
340-
* @param sshKeyPair
341-
* - name of the ssh key pair used to login to the virtual
342-
* machine
353+
* @param userDataId
354+
* @param userDataDetails
343355
* @param requestedIps
344356
* TODO
345357
* @param defaultIps
346358
* TODO
347359
* @param displayVm
348360
* - Boolean flag whether to the display the vm to the end user or not
349361
* @param affinityGroupIdList
350-
* @param cpuSpeed
351-
* @param memory
352-
* @param cpuNumber
353362
* @param customId
354363
* @param dhcpOptionMap
355364
* - Map that maps the DhcpOption code and their value on the Network uuid
@@ -370,10 +379,10 @@ UserVm createAdvancedSecurityGroupVirtualMachine(DataCenter zone, ServiceOfferin
370379
* available.
371380
*/
372381
UserVm createAdvancedVirtualMachine(DataCenter zone, ServiceOffering serviceOffering, VirtualMachineTemplate template, List<Long> networkIdList, Account owner,
373-
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
374-
List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
375-
Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
376-
Map<String, String> templateOvfPropertiesMap, boolean dynamicScalingEnabled, String vmType, Long overrideDiskOfferingId)
382+
String hostName, String displayName, Long diskOfferingId, Long diskSize, String group, HypervisorType hypervisor, HTTPMethod httpmethod, String userData,
383+
Long userDataId, String userDataDetails, List<String> sshKeyPairs, Map<Long, IpAddresses> requestedIps, IpAddresses defaultIps, Boolean displayVm, String keyboard, List<Long> affinityGroupIdList,
384+
Map<String, String> customParameters, String customId, Map<String, Map<Integer, String>> dhcpOptionMap, Map<Long, DiskOffering> dataDiskTemplateToDiskOfferingMap,
385+
Map<String, String> templateOvfPropertiesMap, boolean dynamicScalingEnabled, String vmType, Long overrideDiskOfferingId)
377386

378387
throws InsufficientCapacityException, ConcurrentOperationException, ResourceUnavailableException, StorageUnavailableException, ResourceAllocationException;
379388

api/src/main/java/org/apache/cloudstack/annotation/AnnotationService.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ public interface AnnotationService {
3939

4040
enum EntityType {
4141
VM(true), VOLUME(true), SNAPSHOT(true),
42-
VM_SNAPSHOT(true), INSTANCE_GROUP(true), SSH_KEYPAIR(true),
42+
VM_SNAPSHOT(true), INSTANCE_GROUP(true), SSH_KEYPAIR(true), USER_DATA(true),
4343
NETWORK(true), VPC(true), PUBLIC_IP_ADDRESS(true), VPN_CUSTOMER_GATEWAY(true),
4444
TEMPLATE(true), ISO(true), KUBERNETES_CLUSTER(true),
4545
SERVICE_OFFERING(false), DISK_OFFERING(false), NETWORK_OFFERING(false),

0 commit comments

Comments
 (0)