Dynamic CA and reconcile for network names
This commit is contained in:
@@ -143,8 +143,7 @@ public class BoshDeploymentManifestSchema implements YamlSchema {
|
||||
YAtomicType t_url = f.yatomic("URL");
|
||||
t_url.parseWith(BoshValueParsers.url("http", "https", "file"));
|
||||
|
||||
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_network_name = f.yenumFromDynamicValues("NetworkName", (dc) -> cloudConfigProvider.getModel(dc).getNetworkNames());
|
||||
|
||||
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);
|
||||
|
||||
@@ -76,20 +76,31 @@ public class BoshCommandCloudConfigProvider implements DynamicModelProvider<Clou
|
||||
.thenAnyChild()
|
||||
.thenValAt("name");
|
||||
|
||||
protected static final YamlTraversal NETWORK_NAMES = YamlPath.EMPTY
|
||||
.thenAnyChild()
|
||||
.thenValAt("networks")
|
||||
.thenAnyChild()
|
||||
.thenValAt("name");
|
||||
|
||||
@Override
|
||||
public CloudConfigModel getModel(DynamicSchemaContext dc) throws Exception {
|
||||
String out = executeBoshCloudConfigCommand();
|
||||
CloudConfigResponse response = mapper.readValue(out, CloudConfigResponse.class);
|
||||
String[] blocks = response.getBlocks();
|
||||
Assert.isLegal(blocks!=null);
|
||||
Assert.isLegal(blocks.length==1);
|
||||
String block = getCloudConfigBlock();
|
||||
TextDocument doc = new TextDocument(null, LanguageId.BOSH_CLOUD_CONFIG);
|
||||
doc.setText(blocks[0]);
|
||||
doc.setText(block);
|
||||
YamlFileAST ast = yamlParser.getAST(doc);
|
||||
return new CloudConfigModel() {
|
||||
@Override
|
||||
public Collection<String> getVMTypes() {
|
||||
return VM_TYPE_NAMES.traverseAmbiguously(ast)
|
||||
return getNames(VM_TYPE_NAMES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Collection<String> getNetworkNames() {
|
||||
return getNames(NETWORK_NAMES);
|
||||
}
|
||||
|
||||
private Collection<String> getNames(YamlTraversal namesPath) {
|
||||
return namesPath.traverseAmbiguously(ast)
|
||||
.flatMap(nameNode -> {
|
||||
String name = NodeUtil.asScalar(nameNode);
|
||||
return StringUtil.hasText(name)
|
||||
@@ -98,9 +109,19 @@ public class BoshCommandCloudConfigProvider implements DynamicModelProvider<Clou
|
||||
})
|
||||
.collect(CollectorUtil.toMultiset());
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
protected String getCloudConfigBlock() throws Exception{
|
||||
String out = executeBoshCloudConfigCommand();
|
||||
CloudConfigResponse response = mapper.readValue(out, CloudConfigResponse.class);
|
||||
String[] blocks = response.getBlocks();
|
||||
Assert.isLegal(blocks!=null);
|
||||
Assert.isLegal(blocks.length==1);
|
||||
return blocks[0];
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure how long we wait for the command to fetch cloud config before
|
||||
* raising timeout exception. (The command may block for long amounts of time
|
||||
|
||||
@@ -17,4 +17,5 @@ import java.util.Collection;
|
||||
*/
|
||||
public interface CloudConfigModel {
|
||||
Collection<String> getVMTypes();
|
||||
Collection<String> getNetworkNames();
|
||||
}
|
||||
|
||||
@@ -125,7 +125,7 @@ public class BoshEditorTest {
|
||||
//@Ignore //For now... because not passing yet.
|
||||
@Test public void reconcileCfManifest() throws Exception {
|
||||
Editor editor = harness.newEditorFromClasspath("/workspace/cf-deployment-manifest.yml");
|
||||
cloudConfigProvider.readWith(() -> {
|
||||
cloudConfigProvider.executeCommandWith(() -> {
|
||||
throw new IOException("Couldn't contact the director");
|
||||
});
|
||||
editor.assertProblems(/*NONE*/);
|
||||
@@ -718,17 +718,17 @@ public class BoshEditorTest {
|
||||
"instance_groups:\n" +
|
||||
"- name: foo-group\n" +
|
||||
" networks:\n" +
|
||||
" - name: the-network\n" +
|
||||
" - name: default\n" +
|
||||
" static_ips: []\n" +
|
||||
" default: []\n" +
|
||||
"- name: bar-group\n" +
|
||||
" networks:\n" +
|
||||
" - name: the-network\n" +
|
||||
" - name: default\n" +
|
||||
" static_ips: []\n" +
|
||||
" default: []\n" +
|
||||
"- name: bar-group\n" +
|
||||
" networks:\n" +
|
||||
" - name: the-network\n" +
|
||||
" - name: default\n" +
|
||||
" static_ips: []\n" +
|
||||
" default: []\n" +
|
||||
"releases:\n" +
|
||||
@@ -877,7 +877,7 @@ public class BoshEditorTest {
|
||||
}
|
||||
|
||||
@Test public void reconcileVMTypeWhenCloudConfigUnavailable() throws Exception {
|
||||
cloudConfigProvider.readWith(() -> null);
|
||||
cloudConfigProvider.executeCommandWith(() -> null);
|
||||
Editor editor = harness.newEditor(
|
||||
"name: foo\n" +
|
||||
"instance_groups: \n" +
|
||||
@@ -891,7 +891,7 @@ public class BoshEditorTest {
|
||||
}
|
||||
|
||||
@Test public void reconcileVMTypeWhenCloudConfigThrows() throws Exception {
|
||||
cloudConfigProvider.readWith(() -> { throw new TimeoutException("Reading cloud config timed out"); });
|
||||
cloudConfigProvider.executeCommandWith(() -> { throw new TimeoutException("Reading cloud config timed out"); });
|
||||
Editor editor = harness.newEditor(
|
||||
"name: foo\n" +
|
||||
"instance_groups: \n" +
|
||||
@@ -905,7 +905,7 @@ public class BoshEditorTest {
|
||||
}
|
||||
|
||||
@Test public void contentAssistShowsWarningWhenCloudConfigThrows() throws Exception {
|
||||
cloudConfigProvider.readWith(() -> {
|
||||
cloudConfigProvider.executeCommandWith(() -> {
|
||||
throw new TimeoutException("Reading cloud config timed out");
|
||||
});
|
||||
Editor editor = harness.newEditor(
|
||||
@@ -919,6 +919,58 @@ public class BoshEditorTest {
|
||||
assertContains("Reading cloud config timed out", completion.getDocumentation());
|
||||
}
|
||||
|
||||
@Test public void reconcileNetworkName() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"name: my-first-deployment\n" +
|
||||
"instance_groups:\n" +
|
||||
"- name: my-server\n" +
|
||||
" networks:\n" +
|
||||
" - name: default\n" +
|
||||
" - name: bogus-nw\n"
|
||||
);
|
||||
editor.ignoreProblem(YamlSchemaProblems.MISSING_PROPERTY);
|
||||
editor.assertProblems("bogus-nw|unknown 'NetworkName'. Valid values are: [default]");
|
||||
}
|
||||
|
||||
@Test public void reconcileNetworkName2() throws Exception {
|
||||
cloudConfigProvider.readWith(() ->
|
||||
"networks:\n" +
|
||||
"- name: public-nw\n" +
|
||||
"- name: local-nw"
|
||||
);
|
||||
|
||||
Editor editor = harness.newEditor(
|
||||
"name: my-first-deployment\n" +
|
||||
"instance_groups:\n" +
|
||||
"- name: my-server\n" +
|
||||
" networks:\n" +
|
||||
" - name: public-nw\n" +
|
||||
" - name: local-nw\n" +
|
||||
" - name: bogus-nw\n"
|
||||
);
|
||||
editor.ignoreProblem(YamlSchemaProblems.MISSING_PROPERTY);
|
||||
editor.assertProblems("bogus-nw|unknown 'NetworkName'. Valid values are: [public-nw, local-nw]");
|
||||
}
|
||||
|
||||
@Test public void contentAssistNetworkName() throws Exception {
|
||||
cloudConfigProvider.readWith(() ->
|
||||
"networks:\n" +
|
||||
"- name: public-nw\n" +
|
||||
"- name: local-nw"
|
||||
);
|
||||
|
||||
Editor editor = harness.newEditor(
|
||||
"name: my-first-deployment\n" +
|
||||
"instance_groups:\n" +
|
||||
"- name: my-server\n" +
|
||||
" networks:\n" +
|
||||
" - name: <*>"
|
||||
);
|
||||
editor.assertContextualCompletions("<*>",
|
||||
"local-nw<*>", "public-nw<*>"
|
||||
);
|
||||
}
|
||||
|
||||
@Test public void gotoReleaseDefinition() throws Exception {
|
||||
Editor editor = harness.newEditor(
|
||||
"name: foo\n" +
|
||||
|
||||
@@ -18,12 +18,16 @@ import org.springframework.ide.vscode.commons.util.IOUtil;
|
||||
|
||||
public final class MockCloudConfigProvider extends BoshCommandCloudConfigProvider {
|
||||
|
||||
//TODO: use mockito to create this mock instead of a subclass?
|
||||
|
||||
static final String MOCK_DATA_RSRC = "/cmd-out/cloud-config.json";
|
||||
|
||||
private Callable<String> cloudConfigReader = () -> IOUtil.toString(BoshCommandCloudConfigProviderTest.class.getResourceAsStream(MOCK_DATA_RSRC));
|
||||
private Callable<String> cloudConfigCmdExecutor = () -> IOUtil.toString(BoshCommandCloudConfigProviderTest.class.getResourceAsStream(MOCK_DATA_RSRC));
|
||||
|
||||
private int readCount = 0;
|
||||
|
||||
private Callable<String> reader = null;
|
||||
|
||||
/**
|
||||
* Override with a 'fake' which just returns some mock data. That way we can unit-test
|
||||
* without requiring a real bosh setup.
|
||||
@@ -31,11 +35,25 @@ public final class MockCloudConfigProvider extends BoshCommandCloudConfigProvide
|
||||
@Override
|
||||
protected String executeBoshCloudConfigCommand() throws Exception {
|
||||
readCount++;
|
||||
return cloudConfigReader.call();
|
||||
return cloudConfigCmdExecutor.call();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String getCloudConfigBlock() throws Exception {
|
||||
if (reader==null) {
|
||||
return super.getCloudConfigBlock();
|
||||
}
|
||||
readCount++;
|
||||
return reader.call();
|
||||
}
|
||||
|
||||
public MockCloudConfigProvider executeCommandWith(Callable<String> executor) {
|
||||
this.cloudConfigCmdExecutor = executor;
|
||||
return this;
|
||||
}
|
||||
|
||||
public MockCloudConfigProvider readWith(Callable<String> reader) {
|
||||
this.cloudConfigReader = reader;
|
||||
this.reader = reader;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user