Commit 38af6e0b authored by Spiros Koulouzis's avatar Spiros Koulouzis

remove name from VMs

parent d2a68351
description: TOSCA example
imports:
- nodes: https://raw.githubusercontent.com/skoulouzis/DRIP/DRIP_3.0/TOSCA/types/nodes.yaml
- capabilities: https://raw.githubusercontent.com/skoulouzis/DRIP/DRIP_3.0/TOSCA/types/capabilities.yaml
- policies: https://raw.githubusercontent.com/skoulouzis/DRIP/DRIP_3.0/TOSCA/types/policies.yaml
- interfaces: https://raw.githubusercontent.com/skoulouzis/DRIP/DRIP_3.0/TOSCA/types/interfaces.yml
- nodes: https://raw.githubusercontent.com/skoulouzis/DRIP/DRIP_3.0/TOSCA/types/nodes.yaml
- data: https://raw.githubusercontent.com/skoulouzis/CONF/DRIP_3.0/TOSCA/types/data.yml
- capabilities: https://raw.githubusercontent.com/skoulouzis/DRIP/DRIP_3.0/TOSCA/types/capabilities.yaml
- policies: https://raw.githubusercontent.com/skoulouzis/DRIP/DRIP_3.0/TOSCA/types/policies.yaml
- interfaces: https://raw.githubusercontent.com/skoulouzis/DRIP/DRIP_3.0/TOSCA/types/interfaces.yml
topology_template:
node_templates:
compute:
......@@ -14,7 +15,7 @@ topology_template:
disk_size: 50000 MB
mem_size: 6000 MB
num_cores: 2
os: ubuntu 14.04
os: Ubuntu 18.04
type: tosca.nodes.ARTICONF.VM.Compute
compute_1:
interfaces:
......@@ -24,7 +25,7 @@ topology_template:
disk_size: 50000 MB
mem_size: 6000 MB
num_cores: 2
os: ubuntu 14.04
os: Ubuntu 18.04
type: tosca.nodes.ARTICONF.VM.Compute
compute_2:
interfaces:
......@@ -34,7 +35,7 @@ topology_template:
disk_size: 50000 MB
mem_size: 6000 MB
num_cores: 2
os: ubuntu 14.04.04
os: Ubuntu 18.04
type: tosca.nodes.ARTICONF.VM.Compute
kubernetes:
interfaces:
......@@ -91,17 +92,13 @@ topology_template:
node: kubernetes
relationship: tosca.relationships.HostedOn
type: tosca.nodes.ARTICONF.Container.Application.Docker
topology_1:
properties:
domain: UNC BEN (Chapel Hill, NC USA)
provider: ExoGeni
requirements:
- vm:
capability: tosca.capabilities.ARTICONF.VM
node: compute_2
relationship: tosca.relationships.DependsOn
type: tosca.nodes.ARTICONF.VM.topology
topology:
interfaces:
CloudsStorm:
provision:
inputs:
code_type: SEQ
object_type: SubTopology
properties:
domain: UvA (Amsterdam, The Netherlands) XO Rack
provider: ExoGeni
......@@ -115,6 +112,22 @@ topology_template:
node: compute_1
relationship: tosca.relationships.DependsOn
type: tosca.nodes.ARTICONF.VM.topology
topology_1:
interfaces:
CloudsStorm:
provision:
inputs:
code_type: SEQ
object_type: SubTopology
properties:
domain: UNC BEN (Chapel Hill, NC USA)
provider: ExoGeni
requirements:
- vm:
capability: tosca.capabilities.ARTICONF.VM
node: compute_2
relationship: tosca.relationships.DependsOn
type: tosca.nodes.ARTICONF.VM.topology
wordpress:
artifacts:
image:
......@@ -153,8 +166,7 @@ topology_template:
targets:
- mysql
type: tosca.policies.ARTICONF.FaultTolerance
outputs:
private_ip_compute:
description: The private IP address of the application’s first tier.
......@@ -164,6 +176,6 @@ topology_template:
value: { get_attribute: [compute_1, private_ip] }
private_ip_compute_2:
description: The private IP address of the application’s second tier.
value: { get_attribute: [compute_2, private_ip] }
value: { get_attribute: [compute_2, private_ip] }
tosca_definitions_version: tosca_simple_yaml_1_0
......@@ -28,7 +28,6 @@ import java.util.List;
import java.util.Map;
import nl.uva.sne.drip.model.NodeTemplate;
import nl.uva.sne.drip.model.NodeTemplateMap;
import nl.uva.sne.drip.model.Provisioner;
import nl.uva.sne.drip.model.tosca.Credential;
import nl.uva.sne.drip.model.tosca.ToscaTemplate;
import nl.uva.sne.drip.sure.tosca.client.DefaultApi;
......@@ -42,9 +41,9 @@ import org.springframework.beans.factory.annotation.Autowired;
* @author S. Koulouzis
*/
public class ToscaHelper {
private DefaultApi api;
private ObjectMapper objectMapper;
public static final String VM_CAPABILITY = "tosca.capabilities.ARTICONF.VM";
private static final String VM_TYPE = "tosca.nodes.ARTICONF.VM.Compute";
......@@ -53,7 +52,7 @@ public class ToscaHelper {
private static final String VM_OS = "os";
private static final String VM_TOPOLOGY = "tosca.nodes.ARTICONF.VM.topology";
private Integer id;
@Autowired
public ToscaHelper(String sureToscaBasePath) {
init(sureToscaBasePath);
......@@ -65,14 +64,14 @@ public class ToscaHelper {
public Integer getId() {
return id;
}
private void init(String sureToscaBasePath) {
Configuration.getDefaultApiClient().setBasePath(sureToscaBasePath);
api = new DefaultApi(Configuration.getDefaultApiClient());
this.objectMapper = new ObjectMapper(new YAMLFactory().disable(YAMLGenerator.Feature.WRITE_DOC_START_MARKER));
objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);
}
public void uploadToscaTemplate(ToscaTemplate toscaTemplate) throws JsonProcessingException, IOException, ApiException {
String ymlStr = objectMapper.writeValueAsString(toscaTemplate);
File toscaTemplateFile = File.createTempFile("temp-toscaTemplate", ".yml");
......@@ -80,7 +79,7 @@ public class ToscaHelper {
String resp = api.uploadToscaTemplate(toscaTemplateFile);
id = Integer.valueOf(resp);
}
public List<Map<String, Object>> getProvisionInterfaceDefinitions(List<String> toscaInterfaceTypes) throws ApiException {
List<Map<String, Object>> interfaceDefinitions = new ArrayList<>();
for (String type : toscaInterfaceTypes) {
......@@ -90,12 +89,12 @@ public class ToscaHelper {
}
return interfaceDefinitions;
}
public List<NodeTemplateMap> getVMTopologyTemplates() throws ApiException {
List<NodeTemplateMap> vmTopologyTemplates = api.getNodeTemplates(String.valueOf(id), "tosca.nodes.ARTICONF.VM.topology", null, null, null, null, null, null, null);
return vmTopologyTemplates;
}
public List<NodeTemplateMap> getTemplateVMsForVMTopology(NodeTemplateMap nodeTemplateMap) throws ApiException {
NodeTemplate nodeTemplate = nodeTemplateMap.getNodeTemplate();
List<Map<String, Object>> requirements = nodeTemplate.getRequirements();
......@@ -110,9 +109,9 @@ public class ToscaHelper {
}
}
return vms;
}
public Double getVMNumOfCores(NodeTemplateMap vmMap) throws Exception {
NodeTemplate vm = vmMap.getNodeTemplate();
if (vm.getType().equals(VM_TYPE)) {
......@@ -121,7 +120,7 @@ public class ToscaHelper {
throw new Exception("NodeTemplate is not of type: " + VM_TYPE + " it is of type: " + vm.getType());
}
}
public Double getVMNMemSize(NodeTemplateMap vmMap) throws Exception {
NodeTemplate vm = vmMap.getNodeTemplate();
if (vm.getType().equals(VM_TYPE)) {
......@@ -134,9 +133,9 @@ public class ToscaHelper {
} else {
throw new Exception("NodeTemplate is not of type: " + VM_TYPE + " it is of type: " + vm.getType());
}
}
public String getVMNOS(NodeTemplateMap vmMap) throws Exception {
NodeTemplate vm = vmMap.getNodeTemplate();
if (vm.getType().equals(VM_TYPE)) {
......@@ -145,7 +144,7 @@ public class ToscaHelper {
throw new Exception("NodeTemplate is not of type: " + VM_TYPE + " it is of type: " + vm.getType());
}
}
private Double convertToGB(Integer value, String memUnit) {
switch (memUnit) {
case "GB":
......@@ -158,7 +157,7 @@ public class ToscaHelper {
return null;
}
}
public String getTopologyDomain(NodeTemplateMap nodeTemplateMap) throws Exception {
NodeTemplate nodeTemplate = nodeTemplateMap.getNodeTemplate();
if (nodeTemplate.getType().equals(VM_TOPOLOGY)) {
......@@ -167,7 +166,7 @@ public class ToscaHelper {
throw new Exception("NodeTemplateMap is not of type: " + VM_TOPOLOGY + " it is of type: " + nodeTemplate.getType());
}
}
public String getTopologyProvider(NodeTemplateMap nodeTemplateMap) throws Exception {
NodeTemplate nodeTemplate = nodeTemplateMap.getNodeTemplate();
if (nodeTemplate.getType().equals(VM_TOPOLOGY)) {
......@@ -176,7 +175,7 @@ public class ToscaHelper {
throw new Exception("NodeTemplate is not of type: " + VM_TOPOLOGY + " it is of type: " + nodeTemplate.getType());
}
}
public NodeTemplateMap setCredentialsInVMTopology(NodeTemplateMap vmTopologyMap, Credential credential) throws Exception {
NodeTemplate vmTopology = vmTopologyMap.getNodeTemplate();
if (vmTopology.getType().equals(VM_TOPOLOGY)) {
......@@ -199,7 +198,7 @@ public class ToscaHelper {
throw new Exception("NodeTemplate is not of type: " + VM_TOPOLOGY + " it is of type: " + vmTopology.getType());
}
}
public Credential getCredentialsFromVMTopology(NodeTemplateMap vmTopologyMap) throws Exception {
NodeTemplate vmTopology = vmTopologyMap.getNodeTemplate();
if (vmTopology.getType().equals(VM_TOPOLOGY)) {
......@@ -207,23 +206,22 @@ public class ToscaHelper {
String ymlStr = Converter.map2YmlString((Map<String, Object>) att.get("credential"));
Credential toscaCredential = objectMapper.readValue(ymlStr, Credential.class);
return toscaCredential;
} else {
throw new Exception("NodeTemplate is not of type: " + VM_TOPOLOGY + " it is of type: " + vmTopology.getType());
}
}
public ToscaTemplate setVMTopologyInToscaTemplate(ToscaTemplate toscaTemplate, NodeTemplateMap vmTopologyMap) {
Map<String, NodeTemplate> nodes = toscaTemplate.getTopologyTemplate().getNodeTemplates();
nodes.put(vmTopologyMap.getName(), vmTopologyMap.getNodeTemplate());
return toscaTemplate;
}
public NodeTemplateMap setProvisionerInterfaceInVMTopology(NodeTemplateMap vmTopologyMap, Map<String, Object> provisionInterface) throws ApiException {
vmTopologyMap.getNodeTemplate().setInterfaces(provisionInterface);
return vmTopologyMap;
}
// public NodeTemplateMap setProvisionerInterfaceInVMTopology(NodeTemplateMap vmTopologyMap, Map<String, Object> provisionInterface) throws ApiException {
// vmTopologyMap.getNodeTemplate().setInterfaces(provisionInterface);
// return vmTopologyMap;
// }
private Map<String, Object> getBestProvisionInterfaceDefinition(List<Map<String, Object>> definitions) {
for (Map<String, Object> def : definitions) {
if (def.containsKey("tosca.interfaces.ARTICONF.CloudsStorm")) {
......@@ -232,20 +230,28 @@ public class ToscaHelper {
}
return null;
}
private Map<String, Object> getProvisionInterfaceInstanceDefaultValues(Map<String, Object> definition, String operation) throws ApiException {
String type = definition.keySet().iterator().next();
String[] typeArray = type.split("\\.");
Map<String, Object> provisionInterface = api.getDefaultInterface(String.valueOf(id), type, typeArray[typeArray.length - 1], operation);
// provisionInterface.remove("")
return provisionInterface;
}
public Map<String, Object> getProvisionInterface(Provisioner provisioner, String operation) throws ApiException {
List<String> toscaInterfaceTypes = new ArrayList<>();
toscaInterfaceTypes.add(provisioner.getToscaInterfaceType());
List<Map<String, Object>> definitions = getProvisionInterfaceDefinitions(toscaInterfaceTypes);
Map<String, Object> definition = getBestProvisionInterfaceDefinition(definitions);
Map<String, Object> provisionInterface = getProvisionInterfaceInstanceDefaultValues(definition, operation);
return provisionInterface;
// public Map<String, Object> getProvisionInterface(Provisioner provisioner, String operation) throws ApiException {
// List<String> toscaInterfaceTypes = new ArrayList<>();
// toscaInterfaceTypes.add(provisioner.getToscaInterfaceType());
// List<Map<String, Object>> definitions = getProvisionInterfaceDefinitions(toscaInterfaceTypes);
// Map<String, Object> definition = getBestProvisionInterfaceDefinition(definitions);
// Map<String, Object> provisionInterface = getProvisionInterfaceInstanceDefaultValues(definition, operation);
// return provisionInterface;
// }
public Map<String, Object> getProvisionerInterfaceFromVMTopology(NodeTemplateMap vmTopologyMap) {
return (Map<String, Object>) vmTopologyMap.getNodeTemplate().getInterfaces().get("CloudsStorm");
}
public NodeTemplateMap setProvisionerInterfaceInVMTopology(NodeTemplateMap vmTopologyMap, Map<String, Object> provisionerInterface) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
}
......@@ -227,28 +227,28 @@ public class ToscaHelperTest {
provisioner.setToscaInterfaceType("tosca.interfaces.ARTICONF.CloudsStorm");
String operation = "provision";
for (NodeTemplateMap vmTopologyMap : vmTopologies) {
Map<String, Object> provisionInterface = instance.getProvisionInterface(provisioner, operation);
List<String> objects = new ArrayList<>();
objects.add("subtopology");
String key = provisionInterface.keySet().iterator().next();
Map<String, Object> provisionOperation = (Map<String, Object>) provisionInterface.get(key);
Map<String, Object> operationMap = (Map<String, Object>) provisionOperation.get(operation);
List<Map<String, Object>> inputs = (List<Map<String, Object>>) operationMap.get("inputs");
for (Map<String, Object> input : inputs) {
if (input.containsKey("objects")) {
input.put("objects", objects);
break;
}
}
vmTopologyMap = instance.setProvisionerInterfaceInVMTopology(vmTopologyMap, provisionInterface);
toscaTemplateWithInterface = instance.setVMTopologyInToscaTemplate(toscaTemplate, vmTopologyMap);
}
instance.uploadToscaTemplate(toscaTemplateWithInterface);
topology_1 = toscaTemplateWithCredentials.getTopologyTemplate().getNodeTemplates().get("topology_1");
// for (NodeTemplateMap vmTopologyMap : vmTopologies) {
topology = toscaTemplateWithCredentials.getTopologyTemplate().getNodeTemplates().get("topology");
// Map<String, Object> provisionInterface = instance.getProvisionInterface(provisioner, operation);
// List<String> objects = new ArrayList<>();
// objects.add("subtopology");
// String key = provisionInterface.keySet().iterator().next();
// Map<String, Object> provisionOperation = (Map<String, Object>) provisionInterface.get(key);
// Map<String, Object> operationMap = (Map<String, Object>) provisionOperation.get(operation);
// List<Map<String, Object>> inputs = (List<Map<String, Object>>) operationMap.get("inputs");
// for (Map<String, Object> input : inputs) {
// if (input.containsKey("objects")) {
// input.put("objects", objects);
// break;
// }
// }
// vmTopologyMap = instance.setProvisionerInterfaceInVMTopology(vmTopologyMap, provisionInterface);
// toscaTemplateWithInterface = instance.setVMTopologyInToscaTemplate(toscaTemplate, vmTopologyMap);
//// }
// instance.uploadToscaTemplate(toscaTemplateWithInterface);
// topology_1 = toscaTemplateWithCredentials.getTopologyTemplate().getNodeTemplates().get("topology_1");
//
// topology = toscaTemplateWithCredentials.getTopologyTemplate().getNodeTemplates().get("topology");
instance.uploadToscaTemplate(toscaTemplate);
}
......
......@@ -7,6 +7,7 @@ package nl.uva.sne.drip.service;
import com.fasterxml.jackson.core.JsonProcessingException;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeoutException;
......@@ -17,7 +18,6 @@ import nl.uva.sne.drip.commons.utils.ToscaHelper;
import nl.uva.sne.drip.model.Message;
import nl.uva.sne.drip.model.NodeTemplate;
import nl.uva.sne.drip.model.NodeTemplateMap;
import nl.uva.sne.drip.model.Provisioner;
import nl.uva.sne.drip.model.tosca.Credential;
import nl.uva.sne.drip.model.tosca.ToscaTemplate;
import nl.uva.sne.drip.rpc.DRIPCaller;
......@@ -96,7 +96,6 @@ public class DRIPService {
}
private ToscaTemplate addCredentials(ToscaTemplate toscaTemplate) throws IOException, JsonProcessingException, ApiException, Exception {
// helper.uploadToscaTemplate(toscaTemplate);
List<NodeTemplateMap> vmTopologies = helper.getVMTopologyTemplates();
List<Credential> credentials = null;
for (NodeTemplateMap vmTopologyMap : vmTopologies) {
......@@ -114,36 +113,35 @@ public class DRIPService {
public String plan(String id) throws ApiException, Exception {
String ymlToscaTemplate = toscaTemplateService.findByID(id);
ToscaTemplate toscaTemplate = toscaTemplateService.getYaml2ToscaTemplate(ymlToscaTemplate);
helper.uploadToscaTemplate(toscaTemplate);
return execute(toscaTemplate);
}
public String provision(String id) throws JsonProcessingException, NotFoundException, IOException, Exception {
String ymlToscaTemplate = toscaTemplateService.findByID(id);
ToscaTemplate toscaTemplate = toscaTemplateService.getYaml2ToscaTemplate(ymlToscaTemplate);
helper.uploadToscaTemplate(toscaTemplate);
toscaTemplate = addCredentials(toscaTemplate);
toscaTemplate = addProvisionInterface(toscaTemplate, OPERATION_PROVISION);
toscaTemplate = setProvisionOperation(toscaTemplate, OPERATION_PROVISION);
return execute(toscaTemplate);
}
private ToscaTemplate addProvisionInterface(ToscaTemplate toscaTemplate, String operation) throws IOException, JsonProcessingException, ApiException, Exception {
private ToscaTemplate setProvisionOperation(ToscaTemplate toscaTemplate, String operation) throws IOException, JsonProcessingException, ApiException, Exception {
// helper.uploadToscaTemplate(toscaTemplate);
List<NodeTemplateMap> vmTopologies = helper.getVMTopologyTemplates();
List<Provisioner> provisioners = null;
for (NodeTemplateMap vmTopologyMap : vmTopologies) {
provisioners = provisionerService.findAll();
if (provisioners != null && provisioners.size() > 0) {
Provisioner provisioner = getBestProvisioners(vmTopologyMap.getNodeTemplate(), provisioners);
Map<String, Object> provisionInterface = helper.getProvisionInterface(provisioner, operation);
vmTopologyMap = helper.setProvisionerInterfaceInVMTopology(vmTopologyMap, provisionInterface);
Map<String, Object> provisionerInterface = helper.getProvisionerInterfaceFromVMTopology(vmTopologyMap);
if (!provisionerInterface.containsKey("provision")) {
Map<String, Object> inputsMap = new HashMap<>();
inputsMap.put(operation, caller);
Map<String, Object> provisionMap = new HashMap<>();
provisionMap.put("inputs", inputsMap);
provisionerInterface.put(operation, caller);
vmTopologyMap = helper.setProvisionerInterfaceInVMTopology(vmTopologyMap, provisionerInterface);
toscaTemplate = helper.setVMTopologyInToscaTemplate(toscaTemplate, vmTopologyMap);
}
}
return toscaTemplate;
}
private Provisioner getBestProvisioners(NodeTemplate nodeTemplate, List<Provisioner> provisioners) {
return provisioners.get(0);
}
}
......@@ -59,9 +59,9 @@ public class ServiceTests {
private String toscaTemplateID;
private String testApplicationExampleToscaContents;
private static final String testApplicationExampleToscaFilePath = ".." + File.separator + "TOSCA" + File.separator + "application_example.yaml";
private static final String testApplicationExampleToscaFilePath = ".." + File.separator + "TOSCA" + File.separator + "application_example_updated.yaml";
private static final String testUpdatedApplicationExampleToscaFilePath = ".." + File.separator + "TOSCA" + File.separator + "application_example_updated.yaml";
private static final String testOutputApplicationExampleToscaFilePath = ".." + File.separator + "TOSCA" + File.separator + "application_example_output.yaml";
private static final String testOutputApplicationExampleToscaFilePath = ".." + File.separator + "TOSCA" + File.separator + "application_example_updated.yaml";
@Autowired
CredentialService credentialService;
......
......@@ -2,9 +2,10 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="e478ccae-5352-4e8e-9efb-3f5cda44e877" name="Default Changelist" comment="">
<change beforePath="$PROJECT_DIR$/../TOSCA/types/nodes.yaml" beforeDir="false" afterPath="$PROJECT_DIR$/../TOSCA/types/nodes.yaml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../drip-commons/src/main/java/nl/uva/sne/drip/commons/utils/ToscaHelper.java" beforeDir="false" afterPath="$PROJECT_DIR$/../drip-commons/src/main/java/nl/uva/sne/drip/commons/utils/ToscaHelper.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../drip-commons/src/test/java/nl/uva/sne/drip/commons/utils/ToscaHelperTest.java" beforeDir="false" afterPath="$PROJECT_DIR$/../drip-commons/src/test/java/nl/uva/sne/drip/commons/utils/ToscaHelperTest.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/service/DRIPService.java" beforeDir="false" afterPath="$PROJECT_DIR$/../drip-manager/src/main/java/nl/uva/sne/drip/service/DRIPService.java" afterDir="false" />
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
<change beforePath="$PROJECT_DIR$/util/tosca_helper.py" beforeDir="false" afterPath="$PROJECT_DIR$/util/tosca_helper.py" afterDir="false" />
</list>
<option name="SHOW_DIALOG" value="false" />
<option name="HIGHLIGHT_CONFLICTS" value="true" />
......@@ -45,7 +46,7 @@
<recent name="$PROJECT_DIR$/test" />
</key>
</component>
<component name="RunManager" selected="Python tests.Unittests for test_planner.MyTestCase.test_planner">
<component name="RunManager" selected="Python.__main__">
<configuration name="__main__" type="PythonConfigurationType" factoryName="Python" temporary="true">
<module name="drip-planner" />
<option name="INTERPRETER_OPTIONS" value="" />
......@@ -117,9 +118,9 @@
</list>
<recent_temporary>
<list>
<item itemvalue="Python.__main__" />
<item itemvalue="Python tests.Unittests for test_planner.MyTestCase.test_planner" />
<item itemvalue="Python tests.Unittests in test_planner.py" />
<item itemvalue="Python.__main__" />
<item itemvalue="Python tests.Unittests for test_planner.MyTestCase.test_something" />
</list>
</recent_temporary>
......@@ -270,42 +271,42 @@
<screen x="67" y="34" width="2493" height="1406" />
</state>
<state x="1043" y="437" width="530" height="598" key="FileChooserDialogImpl/67.34.2493.1406@67.34.2493.1406" timestamp="1575907769017" />
<state width="2465" height="413" key="GridCell.Tab.0.bottom" timestamp="1577716871173">
<state width="2465" height="413" key="GridCell.Tab.0.bottom" timestamp="1577720249205">
<screen x="67" y="34" width="2493" height="1406" />
</state>
<state width="1825" height="283" key="GridCell.Tab.0.bottom/67.34.1853.1046@67.34.1853.1046" timestamp="1576165782177" />
<state width="2465" height="413" key="GridCell.Tab.0.bottom/67.34.2493.1406@67.34.2493.1406" timestamp="1577716871173" />
<state width="2465" height="413" key="GridCell.Tab.0.center" timestamp="1577716871171">
<state width="2465" height="413" key="GridCell.Tab.0.bottom/67.34.2493.1406@67.34.2493.1406" timestamp="1577720249205" />
<state width="2465" height="413" key="GridCell.Tab.0.center" timestamp="1577720249202">
<screen x="67" y="34" width="2493" height="1406" />
</state>
<state width="1825" height="283" key="GridCell.Tab.0.center/67.34.1853.1046@67.34.1853.1046" timestamp="1576165782175" />
<state width="2465" height="413" key="GridCell.Tab.0.center/67.34.2493.1406@67.34.2493.1406" timestamp="1577716871171" />
<state width="2465" height="413" key="GridCell.Tab.0.left" timestamp="1577716871170">
<state width="2465" height="413" key="GridCell.Tab.0.center/67.34.2493.1406@67.34.2493.1406" timestamp="1577720249202" />
<state width="2465" height="413" key="GridCell.Tab.0.left" timestamp="1577720249200">
<screen x="67" y="34" width="2493" height="1406" />
</state>
<state width="1825" height="283" key="GridCell.Tab.0.left/67.34.1853.1046@67.34.1853.1046" timestamp="1576165782174" />
<state width="2465" height="413" key="GridCell.Tab.0.left/67.34.2493.1406@67.34.2493.1406" timestamp="1577716871170" />
<state width="2465" height="413" key="GridCell.Tab.0.right" timestamp="1577716871172">
<state width="2465" height="413" key="GridCell.Tab.0.left/67.34.2493.1406@67.34.2493.1406" timestamp="1577720249200" />
<state width="2465" height="413" key="GridCell.Tab.0.right" timestamp="1577720249203">
<screen x="67" y="34" width="2493" height="1406" />
</state>
<state width="1825" height="283" key="GridCell.Tab.0.right/67.34.1853.1046@67.34.1853.1046" timestamp="1576165782176" />
<state width="2465" height="413" key="GridCell.Tab.0.right/67.34.2493.1406@67.34.2493.1406" timestamp="1577716871172" />
<state width="2465" height="413" key="GridCell.Tab.1.bottom" timestamp="1577716830929">
<state width="2465" height="413" key="GridCell.Tab.0.right/67.34.2493.1406@67.34.2493.1406" timestamp="1577720249203" />
<state width="2465" height="413" key="GridCell.Tab.1.bottom" timestamp="1577720249209">
<screen x="67" y="34" width="2493" height="1406" />
</state>
<state width="2465" height="413" key="GridCell.Tab.1.bottom/67.34.2493.1406@67.34.2493.1406" timestamp="1577716830929" />
<state width="2465" height="413" key="GridCell.Tab.1.center" timestamp="1577716830929">
<state width="2465" height="413" key="GridCell.Tab.1.bottom/67.34.2493.1406@67.34.2493.1406" timestamp="1577720249209" />
<state width="2465" height="413" key="GridCell.Tab.1.center" timestamp="1577720249207">
<screen x="67" y="34" width="2493" height="1406" />
</state>
<state width="2465" height="413" key="GridCell.Tab.1.center/67.34.2493.1406@67.34.2493.1406" timestamp="1577716830929" />
<state width="2465" height="413" key="GridCell.Tab.1.left" timestamp="1577716830929">
<state width="2465" height="413" key="GridCell.Tab.1.center/67.34.2493.1406@67.34.2493.1406" timestamp="1577720249207" />
<state width="2465" height="413" key="GridCell.Tab.1.left" timestamp="1577720249206">
<screen x="67" y="34" width="2493" height="1406" />
</state>
<state width="2465" height="413" key="GridCell.Tab.1.left/67.34.2493.1406@67.34.2493.1406" timestamp="1577716830929" />
<state width="2465" height="413" key="GridCell.Tab.1.right" timestamp="1577716830929">
<state width="2465" height="413" key="GridCell.Tab.1.left/67.34.2493.1406@67.34.2493.1406" timestamp="1577720249206" />
<state width="2465" height="413" key="GridCell.Tab.1.right" timestamp="1577720249208">
<screen x="67" y="34" width="2493" height="1406" />
</state>
<state width="2465" height="413" key="GridCell.Tab.1.right/67.34.2493.1406@67.34.2493.1406" timestamp="1577716830929" />
<state width="2465" height="413" key="GridCell.Tab.1.right/67.34.2493.1406@67.34.2493.1406" timestamp="1577720249208" />
<state x="679" y="283" key="SettingsEditor" timestamp="1575885393075">
<screen x="67" y="34" width="2493" height="1406" />
</state>
......
CloudsStormVMs:
type: "object"
properties:
name:
type: "string"
CloudsStormVM:
VMs:
type: "array"
items:
$ref: "https://raw.githubusercontent.com/skoulouzis/CONF/DRIP_3.0/openAPI/schema/CloudStorm/CloudsStormVM.yml#/CloudsStormVM"
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment