Define (first-level) nested properties for instance_groups
This commit is contained in:
@@ -14,6 +14,7 @@ import java.util.UUID;
|
||||
|
||||
import org.springframework.ide.vscode.commons.util.Renderable;
|
||||
import org.springframework.ide.vscode.commons.util.Renderables;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParser;
|
||||
import org.springframework.ide.vscode.commons.util.ValueParsers;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YType;
|
||||
import org.springframework.ide.vscode.commons.yaml.schema.YTypeFactory;
|
||||
@@ -55,8 +56,35 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
|
||||
|
||||
TOPLEVEL_TYPE = f.ybean("BoshDeploymentManifest");
|
||||
addProp(TOPLEVEL_TYPE, "name", t_ne_string).isPrimary(true);
|
||||
addProp(TOPLEVEL_TYPE, "director_uuid", t_uuid)
|
||||
.isRequired(true);
|
||||
addProp(TOPLEVEL_TYPE, "director_uuid", t_uuid).isDeprecated(
|
||||
"bosh v2 CLI no longer checks or requires director_uuid in the deployment manifest. " +
|
||||
"To achieve similar safety make sure to give unique deployment names across environments."
|
||||
);
|
||||
|
||||
YAtomicType t_network_name = f.yatomic("NetworkName"); //TODO: resolve from 'cloud config' https://www.pivotaltracker.com/story/show/148712155
|
||||
t_network_name.parseWith(ValueParsers.NE_STRING);
|
||||
|
||||
YAtomicType t_disk_type = f.yatomic("DiskType"); //TODO: resolve from 'cloud config' https://www.pivotaltracker.com/story/show/148704001
|
||||
t_disk_type.parseWith(ValueParsers.NE_STRING);
|
||||
|
||||
YAtomicType t_stemcell_alias = f.yatomic("StemcellAlias"); //TODO: resolve from 'stemcells block' https://www.pivotaltracker.com/story/show/148706041
|
||||
t_stemcell_alias.parseWith(ValueParsers.NE_STRING);
|
||||
|
||||
YAtomicType t_vm_extension = f.yatomic("VMExtension"); //TODO: resolve dynamically from 'cloud config' ? https://www.pivotaltracker.com/story/show/148703877
|
||||
t_vm_extension.parseWith(ValueParsers.NE_STRING);
|
||||
|
||||
YAtomicType t_vm_type = f.yatomic("VMType"); //TODO: resolve dynamically from 'cloud config' ? https://www.pivotaltracker.com/story/show/148686169
|
||||
t_vm_type.parseWith(ValueParsers.NE_STRING);
|
||||
|
||||
YAtomicType t_az = f.yatomic("AvailabilityZone"); //TODO: resolve dynamically from 'cloud config': https://www.pivotaltracker.com/story/show/148704481
|
||||
t_az.parseWith(ValueParsers.NE_STRING);
|
||||
|
||||
YBeanType t_network = f.ybean("Network");
|
||||
addProp(t_network, "name", t_network_name).isRequired(true);
|
||||
|
||||
YBeanType t_instance_group_env = f.ybean("InstanceGroupEnv");
|
||||
addProp(t_instance_group_env, "npsh", t_params);
|
||||
addProp(t_instance_group_env, "password", t_ne_string);
|
||||
|
||||
YAtomicType t_version = f.yatomic("Version");
|
||||
t_version.addHints("latest");
|
||||
@@ -77,8 +105,31 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
|
||||
|
||||
YType t_update = t_params; //TODO: https://www.pivotaltracker.com/story/show/148627121
|
||||
addProp(TOPLEVEL_TYPE, "update", t_update).isRequired(true);
|
||||
|
||||
YType t_instance_group = t_params; //TODO: https://www.pivotaltracker.com/story/show/148627211
|
||||
|
||||
YBeanType t_job = f.ybean("Job");
|
||||
addProp(t_job, "name", t_ne_string).isPrimary(true);
|
||||
addProp(t_job, "release", t_ne_string).isRequired(true);
|
||||
addProp(t_job, "consumes", t_params);
|
||||
addProp(t_job, "provides", t_params);
|
||||
addProp(t_job, "properties", t_params).isRequired(true);
|
||||
|
||||
YBeanType t_instance_group = f.ybean("InstanceGroup");
|
||||
addProp(t_instance_group, "name", t_ne_string).isPrimary(true);
|
||||
addProp(t_instance_group, "azs", f.yseq(t_az)).isRequired(true);
|
||||
addProp(t_instance_group, "instances", t_pos_integer).isRequired(true); //Strictly positive? Or zero is okay?
|
||||
addProp(t_instance_group, "jobs", f.yseq(t_job)).isRequired(true);
|
||||
addProp(t_instance_group, "vm_type", t_vm_type).isRequired(true);
|
||||
addProp(t_instance_group, "vm_extensions", f.yseq(t_vm_extension));
|
||||
addProp(t_instance_group, "stemcell", t_stemcell_alias).isRequired(true);
|
||||
addProp(t_instance_group, "persistent_disk_type", t_disk_type);
|
||||
addProp(t_instance_group, "networks", f.yseq(t_network));
|
||||
addProp(t_instance_group, "update", t_update);
|
||||
YType t_migration = t_params; //TODO: https://www.pivotaltracker.com/story/show/148712595
|
||||
addProp(t_instance_group, "migrated_from", f.yseq(t_migration));
|
||||
addProp(t_instance_group, "lifecycle", f.yenum("WorkloadType", "service", "errand"));
|
||||
addProp(t_instance_group, "properties", t_params).isDeprecated("Deprecated in favor of job level properties and links");
|
||||
addProp(t_instance_group, "env", t_instance_group_env);
|
||||
|
||||
addProp(TOPLEVEL_TYPE, "instance_groups", f.yseq(t_instance_group)).isRequired(true);
|
||||
|
||||
addProp(TOPLEVEL_TYPE, "properties", t_params).isDeprecated("Deprecated in favor of job level properties and links");
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
*Required*. List of AZs associated with this instance group (should only be used when using [first class AZs](https://bosh.io/docs/azs.html) ). Example: `[z1, z2]`.
|
||||
@@ -0,0 +1 @@
|
||||
*Optional*. Specifies advanced BOSH Agent configuration for each instance in the group.
|
||||
@@ -0,0 +1 @@
|
||||
*Required*. The number of instances in this group. Each instance is a VM.
|
||||
@@ -0,0 +1 @@
|
||||
*Required*. Specifies the name and release of jobs that will be installed on each instance.
|
||||
@@ -0,0 +1 @@
|
||||
Specifies the kind of workload the instance group represents. Valid values are `service` and `errand`; defaults to `service`. A `service` runs indefinitely and restarts if it fails. An `errand` starts with a manual trigger and does not restart if it fails.
|
||||
@@ -0,0 +1 @@
|
||||
*Optional*. Specific migration settings for this instance group. Use this to [rename and/or migrate instance groups](https://bosh.io/docs/migrated-from.html).
|
||||
@@ -0,0 +1 @@
|
||||
*Required*. A unique name used to identify and reference the instance group.
|
||||
@@ -0,0 +1 @@
|
||||
*Required*. Specifies the networks this instance requires.
|
||||
@@ -0,0 +1 @@
|
||||
*Optional*. A valid disk type name from the cloud config. [Read more about persistent disks](https://bosh.io/docs/persistent-disks.html)
|
||||
@@ -0,0 +1 @@
|
||||
*Optional*. Specifies instance group properties. Deprecated in favor of job level properties and links.
|
||||
@@ -0,0 +1 @@
|
||||
*Required*. A valid stemcell alias from the Stemcells Block.
|
||||
@@ -0,0 +1 @@
|
||||
*Optional*. Specific update settings for this instance group. Use this to override [global job update settings](https://bosh.io/docs/manifest-v2.html#update) on a per-instance-group basis.
|
||||
@@ -0,0 +1 @@
|
||||
*Optional*. A valid list of VM extension names from the cloud config.
|
||||
@@ -0,0 +1 @@
|
||||
*Required*. A valid VM type name from the cloud config.
|
||||
@@ -11,6 +11,7 @@
|
||||
package org.springframework.ide.vscode.concourse;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.springframework.ide.vscode.bosh.BoshLanguageServer;
|
||||
import org.springframework.ide.vscode.commons.util.text.LanguageId;
|
||||
@@ -98,6 +99,7 @@ public class BoshEditorTest {
|
||||
"blah: hoooo\n"
|
||||
);
|
||||
editor.assertProblems(
|
||||
"director_uuid|bosh v2 CLI no longer checks or requires",
|
||||
"properties|Deprecated in favor of job level properties and links",
|
||||
"blah|Unknown property"
|
||||
);
|
||||
@@ -128,13 +130,12 @@ public class BoshEditorTest {
|
||||
|
||||
editor.assertCompletions(
|
||||
"name: blah\n" +
|
||||
"director_uuid: <*>"
|
||||
"instance_groups:\n" +
|
||||
"- name: <*>"
|
||||
, // ============
|
||||
"name: blah\n" +
|
||||
"instance_groups:\n- <*>"
|
||||
, // ============
|
||||
"name: blah\n" +
|
||||
"releases:\n- <*>"
|
||||
"releases:\n" +
|
||||
"- name: <*>"
|
||||
, // ============
|
||||
"name: blah\n" +
|
||||
"stemcells:\n- <*>"
|
||||
@@ -149,6 +150,9 @@ public class BoshEditorTest {
|
||||
"variables:\n- <*>"
|
||||
, // ============
|
||||
"name: blah\n" +
|
||||
"director_uuid: <*>"
|
||||
, // ============
|
||||
"name: blah\n" +
|
||||
"properties:\n <*>"
|
||||
);
|
||||
}
|
||||
@@ -186,7 +190,7 @@ public class BoshEditorTest {
|
||||
editor.assertProblems(
|
||||
"-|One of [name, os] is required",
|
||||
"-|[alias, version] are required",
|
||||
"}|[director_uuid, instance_groups, name, releases, update] are required"
|
||||
"}|[instance_groups, name, releases, update] are required"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -236,12 +240,164 @@ public class BoshEditorTest {
|
||||
editor.assertCompletionLabels("latest");
|
||||
}
|
||||
|
||||
@Test public void temp_instanceGroupsCompletions() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" job<*>"
|
||||
);
|
||||
editor.assertCompletions(
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" jobs:\n" +
|
||||
" - name: <*>"
|
||||
);
|
||||
}
|
||||
|
||||
@Test public void instanceGroupsCompletions() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"instance_groups:\n" +
|
||||
"- <*>"
|
||||
);
|
||||
|
||||
editor.assertCompletions(
|
||||
"instance_groups:\n" +
|
||||
"- name: <*>"
|
||||
);
|
||||
|
||||
editor = harness.newEditor(
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" <*>"
|
||||
);
|
||||
editor.assertCompletions(PLAIN_COMPLETION,
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" azs:\n" +
|
||||
" - <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" env:\n" +
|
||||
" <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" instances: <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" jobs:\n" +
|
||||
" - name: <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" lifecycle: <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" migrated_from:\n" +
|
||||
" - <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" networks:\n" +
|
||||
" - name: <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" persistent_disk_type: <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" stemcell: <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" update:\n" +
|
||||
" <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" vm_extensions:\n" +
|
||||
" - <*>"
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" vm_type: <*>"
|
||||
|
||||
, // =============
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" properties:\n" +
|
||||
" <*>"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@Test public void instanceGroupsHovers() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"instance_groups:\n" +
|
||||
"- name: redis-master\n" +
|
||||
" properties: {}\n" +
|
||||
" instances: 1\n" +
|
||||
" azs: [z1, z2]\n" +
|
||||
" jobs:\n" +
|
||||
" - name: redis-server\n" +
|
||||
" release: redis\n" +
|
||||
" properties:\n" +
|
||||
" port: 3606\n" +
|
||||
" vm_type: medium\n" +
|
||||
" vm_extensions: [public-lbs]\n" +
|
||||
" stemcell: default\n" +
|
||||
" persistent_disk_type: medium\n" +
|
||||
" networks:\n" +
|
||||
" - name: default\n" +
|
||||
"\n" +
|
||||
"- name: redis-slave\n" +
|
||||
" instances: 2\n" +
|
||||
" azs: [z1, z2]\n" +
|
||||
" jobs:\n" +
|
||||
" - name: redis-server\n" +
|
||||
" release: redis\n" +
|
||||
" properties: {}\n" +
|
||||
" update:\n" +
|
||||
" canaries: 2\n" +
|
||||
" lifecycle: errand\n" +
|
||||
" migrated_from: []\n" +
|
||||
" env: {}\n" +
|
||||
" vm_type: medium\n" +
|
||||
" stemcell: default\n" +
|
||||
" persistent_disk_type: medium\n" +
|
||||
" networks:\n" +
|
||||
" - name: default\n"
|
||||
);
|
||||
editor.assertHoverContains("name", "A unique name used to identify and reference the instance group.");
|
||||
editor.assertHoverContains("azs", "List of AZs associated with this instance group");
|
||||
editor.assertHoverContains("instances", "The number of instances in this group");
|
||||
editor.assertHoverContains("jobs", "Specifies the name and release of jobs that will be installed on each instance.");
|
||||
editor.assertHoverContains("vm_type", "A valid VM type name from the cloud config");
|
||||
editor.assertHoverContains("vm_extensions", "A valid list of VM extension names from the cloud config");
|
||||
editor.assertHoverContains("stemcell", "A valid stemcell alias from the Stemcells Block");
|
||||
editor.assertHoverContains("persistent_disk_type", "A valid disk type name from the cloud config.");
|
||||
editor.assertHoverContains("networks", "Specifies the networks this instance requires");
|
||||
editor.assertHoverContains("update", "Specific update settings for this instance group");
|
||||
editor.assertHoverContains("migrated_from", "Specific migration settings for this instance group.");
|
||||
editor.assertHoverContains("lifecycle", "Specifies the kind of workload");
|
||||
editor.assertHoverContains("properties", "Specifies instance group properties");
|
||||
editor.assertHoverContains("env", "Specifies advanced BOSH Agent configuration");
|
||||
}
|
||||
|
||||
@Ignore @Test public void instanceGroups_job_hovers() throws Exception {
|
||||
//For the nested properties of instance_groups.jobs
|
||||
throw new IllegalStateException("Implement a test please!");
|
||||
}
|
||||
|
||||
@Ignore @Test public void instanceGroups_network_hovers() throws Exception {
|
||||
//For the nested properties of instance_groups.networks
|
||||
throw new IllegalStateException("Implement a test please!");
|
||||
}
|
||||
|
||||
@Ignore @Test public void instanceGroups_env_hovers() throws Exception {
|
||||
throw new IllegalStateException("Implement a test please!");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ public class AppendTextBuilder {
|
||||
//ready to enter sequence element on next line
|
||||
newline(text, indent);
|
||||
text.append("- ");
|
||||
singleRequiredProperty(typeUtil.getDomainType(type), indent+2, text);
|
||||
singleMostImportantProperty(typeUtil.getDomainType(type), indent+2, text);
|
||||
//Yes using 2 here instead of YamlIndentUtil.INDENT_BY is deliberate. It's the same value (now),
|
||||
// but the 2 used here is the width of the "- " which should determine nested indent level for things to
|
||||
// line up properly.
|
||||
@@ -66,14 +66,18 @@ public class AppendTextBuilder {
|
||||
}
|
||||
}
|
||||
|
||||
private void singleRequiredProperty(YType type, int indent, StringBuilder text) {
|
||||
private void singleMostImportantProperty(YType type, int indent, StringBuilder text) {
|
||||
if (type!=null) {
|
||||
YTypedProperty requireProp = Streams.getSingle(typeUtil.getProperties(type).stream()
|
||||
.filter(p -> p.isRequired()));
|
||||
if (requireProp!=null) {
|
||||
text.append(requireProp.getName());
|
||||
YTypedProperty singleProp = Streams.getSingle(typeUtil.getProperties(type).stream()
|
||||
.filter(p -> p.isPrimary()));
|
||||
if (singleProp==null) {
|
||||
singleProp = Streams.getSingle(typeUtil.getProperties(type).stream()
|
||||
.filter(p -> p.isRequired()));
|
||||
}
|
||||
if (singleProp!=null) {
|
||||
text.append(singleProp.getName());
|
||||
text.append(':');
|
||||
build(requireProp.getType(), indent+YamlIndentUtil.INDENT_BY, text);
|
||||
build(singleProp.getType(), indent+YamlIndentUtil.INDENT_BY, text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -473,7 +473,7 @@ public class ConcourseEditorTest {
|
||||
editor = harness.newEditor("jo<*>");
|
||||
editor.assertCompletions(
|
||||
"jobs:\n"+
|
||||
"- <*>"
|
||||
"- name: <*>"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -486,19 +486,19 @@ public class ConcourseEditorTest {
|
||||
"- name: <*>"
|
||||
, // --------------
|
||||
"jobs:\n" +
|
||||
"- <*>"
|
||||
"- name: <*>"
|
||||
, // ---------------
|
||||
"resource_types:\n" +
|
||||
"- <*>"
|
||||
"- name: <*>"
|
||||
, // ---------------
|
||||
"resources:\n"+
|
||||
"- <*>"
|
||||
"- name: <*>"
|
||||
);
|
||||
|
||||
editor = harness.newEditor("rety<*>");
|
||||
editor.assertCompletions(
|
||||
"resource_types:\n" +
|
||||
"- <*>"
|
||||
"- name: <*>"
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user