From f615f171d14afcd5da1e90db7b86106536fc753c Mon Sep 17 00:00:00 2001 From: Kris De Volder Date: Sun, 29 Jan 2017 10:01:06 -0800 Subject: [PATCH] Support for 'pool' resource type --- .../commons/yaml/schema/YTypeFactory.java | 8 ++ .../vscode/concourse/PipelineYmlSchema.java | 40 +++++-- .../resources/desc/PoolPutParams/acquire.md | 3 + .../main/resources/desc/PoolPutParams/add.md | 4 + .../desc/PoolPutParams/add_claimed.md | 1 + .../resources/desc/PoolPutParams/claim.md | 3 + .../resources/desc/PoolPutParams/release.md | 8 ++ .../resources/desc/PoolPutParams/remove.md | 4 + .../main/resources/desc/PoolSource/branch.md | 1 + .../resources/desc/PoolSource/password.md | 1 + .../main/resources/desc/PoolSource/pool.md | 1 + .../resources/desc/PoolSource/private_key.md | 10 ++ .../resources/desc/PoolSource/retry_delay.md | 3 + .../src/main/resources/desc/PoolSource/uri.md | 1 + .../resources/desc/PoolSource/username.md | 2 + .../vscode/concourse/ConcourseEditorTest.java | 104 ++++++++++++++++++ 16 files changed, 186 insertions(+), 8 deletions(-) create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/acquire.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/add.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/add_claimed.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/claim.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/release.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/remove.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/branch.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/password.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/pool.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/private_key.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/retry_delay.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/uri.md create mode 100644 vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/username.md diff --git a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java index c78ccf32b..1dcce0c41 100644 --- a/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java +++ b/vscode-extensions/commons/commons-yaml/src/main/java/org/springframework/ide/vscode/commons/yaml/schema/YTypeFactory.java @@ -19,6 +19,7 @@ import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.Set; +import java.util.TreeSet; import java.util.concurrent.Callable; import java.util.function.BiFunction; import java.util.stream.Collectors; @@ -294,6 +295,13 @@ public class YTypeFactory { Assert.isLegal(properties.length>1); this.oneOfConstraints.add(properties); } + + public String[] getPropertyNames() { + return getProperties().stream() + .map(YTypedProperty::getName) + .collect(Collectors.toCollection(TreeSet::new)) + .toArray(new String[0]); + } } /** diff --git a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java index 108bfe74b..8dd62c0a0 100644 --- a/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java +++ b/vscode-extensions/vscode-concourse/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java @@ -99,6 +99,9 @@ public class PipelineYmlSchema implements YamlSchema { .parseWith(ValueParsers.NE_STRING) .addHints(MimeTypes.getKnownMimeTypes()); + public final YType t_duration = f.yatomic("Duration") + .parseWith(ConcourseValueParsers.DURATION); + public final AbstractType task; private final ResourceTypeRegistry resourceTypes = new ResourceTypeRegistry(); @@ -109,9 +112,6 @@ public class PipelineYmlSchema implements YamlSchema { // define schema types TOPLEVEL_TYPE = f.ybean("Pipeline"); - YAtomicType t_duration = f.yatomic("Duration"); - t_duration.parseWith(ConcourseValueParsers.DURATION); - YAtomicType t_version = f.yatomic("Version"); t_version.addHints("latest", "every"); @@ -208,7 +208,7 @@ public class PipelineYmlSchema implements YamlSchema { YBeanType putStep = f.ybean("PutStep"); addProp(putStep, "put", t_resource_name); - addProp(putStep, "resource", t_job_name); + addProp(putStep, "resource", t_resource_name); addProp(putStep, "params", f.contextAware("PutParams", (dc) -> resourceTypes.getOutParamsType(getResourceType("put", models, dc)) )); @@ -291,8 +291,8 @@ public class PipelineYmlSchema implements YamlSchema { AbstractType source = f.ybean("GitSource"); addProp(source, "uri", t_string).isRequired(true); addProp(source, "branch", t_string).isRequired(true); - addProp(source, "private_key", t_string); - addProp(source, "username", t_string); + addProp(source, "private_key", t_ne_string); + addProp(source, "username", t_ne_string); addProp(source, "password", t_string); addProp(source, "paths", t_strings); addProp(source, "ignore_paths", t_strings); @@ -369,8 +369,6 @@ public class PipelineYmlSchema implements YamlSchema { } //s3 { - String[] validRegions = { - }; YType t_s3_region = f.yenum("S3Region", //See: http://docs.aws.amazon.com/AmazonS3/latest/API/RESTBucketPUT.html "us-west-1", "us-west-2", @@ -414,6 +412,32 @@ public class PipelineYmlSchema implements YamlSchema { resourceTypes.def("s3", source, get, put); } + //pool + { + AbstractType source = f.ybean("PoolSource"); + addProp(source, "uri", t_ne_string).isRequired(true); + addProp(source, "branch", t_ne_string).isRequired(true); + addProp(source, "pool", t_ne_string).isRequired(true); + addProp(source, "private_key", t_ne_string); + addProp(source, "username", t_ne_string); + addProp(source, "password", t_string); + addProp(source, "retry_delay", t_duration); + + AbstractType get = f.ybean("PoolGetParams"); + //get params deliberately left empty + + AbstractType put = f.ybean("PoolPutParams"); + addProp(put, "acquire", t_boolean); + addProp(put, "claim", t_ne_string); + addProp(put, "release", t_ne_string); + addProp(put, "add", t_ne_string); + addProp(put, "add_claimed", t_ne_string); + addProp(put, "remove", t_ne_string); + put.requireOneOf(put.getPropertyNames()); + + resourceTypes.def("pool", source, get, put); + } + } private String getResourceType(String resourceNameProp, ConcourseModel models, DynamicSchemaContext dc) { diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/acquire.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/acquire.md new file mode 100644 index 000000000..60f66b773 --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/acquire.md @@ -0,0 +1,3 @@ +If true, we will attempt to move a randomly chosen lock from the +pool's unclaimed directory to the claimed directory. Acquiring will retry +until a lock becomes available. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/add.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/add.md new file mode 100644 index 000000000..5b179306b --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/add.md @@ -0,0 +1,4 @@ +If set, we will add a new lock to the pool in the unclaimed state. The +value is the path to a directory containing the files `name` and `metadata` +which should contain the name of your new lock and the contents you would like +in the lock, respectively. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/add_claimed.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/add_claimed.md new file mode 100644 index 000000000..0939518de --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/add_claimed.md @@ -0,0 +1 @@ +Exactly the same as the `add` param, but adds a lock to the pool in the *claimed* state. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/claim.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/claim.md new file mode 100644 index 000000000..635e3d973 --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/claim.md @@ -0,0 +1,3 @@ +If set, the specified lock from the pool will be acquired, rather +than a random one (as in `acquire`). Like `acquire`, claiming will retry +until the specific lock becomes available \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/release.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/release.md new file mode 100644 index 000000000..60be75b5f --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/release.md @@ -0,0 +1,8 @@ +If set, we will release the lock by moving it from claimed to +unclaimed. The value is the path of the lock to release (a directory +containing `name` and `metadata`), which typically is just the step that +provided the lock (either a `get` to pass one along or a `put` to acquire). + +Note: the lock must be available in your job before you can release it. In +other words, a `get` step to fetch metadata about the lock is necessary +before a `put` step can release the lock. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/remove.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/remove.md new file mode 100644 index 000000000..23e0c0aaf --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolPutParams/remove.md @@ -0,0 +1,4 @@ +If set, we will remove the given lock from the pool. The value is +the same as `release`. This can be used for e.g. tearing down an environment, +or moving a lock between pools by using `add` with a different pool in a +second step. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/branch.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/branch.md new file mode 100644 index 000000000..1fb447919 --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/branch.md @@ -0,0 +1 @@ +*Required.* The branch to track. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/password.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/password.md new file mode 100644 index 000000000..e48119630 --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/password.md @@ -0,0 +1 @@ +*Optional.* Password for HTTP(S) auth when pulling/pushing. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/pool.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/pool.md new file mode 100644 index 000000000..7cab7c010 --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/pool.md @@ -0,0 +1 @@ +*Required.* The logical name of your pool of things to lock. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/private_key.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/private_key.md new file mode 100644 index 000000000..477801d95 --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/private_key.md @@ -0,0 +1,10 @@ +*Optional.* Private key to use when pulling/pushing. Ensure it does not require a password. + +Example: + + private_key: | + -----BEGIN RSA PRIVATE KEY----- + MIIEowIBAAKCAQEAtCS10/f7W7lkQaSgD/mVeaSOvSF9ql4hf/zfMwfVGgHWjj+W + + DWiJL+OFeg9kawcUL6hQ8JeXPhlImG6RTUffma9+iGQyyBMCGd1l + -----END RSA PRIVATE KEY----- diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/retry_delay.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/retry_delay.md new file mode 100644 index 000000000..85740560e --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/retry_delay.md @@ -0,0 +1,3 @@ +*Optional.* If specified, dictates how long to wait until retrying +to acquire a lock or release a lock. The default is 10 seconds. +Valid values: `60s`, `90m`, `1h`. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/uri.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/uri.md new file mode 100644 index 000000000..967245f59 --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/uri.md @@ -0,0 +1 @@ +*Required.* The location of the repository. \ No newline at end of file diff --git a/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/username.md b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/username.md new file mode 100644 index 000000000..4a8ff53bf --- /dev/null +++ b/vscode-extensions/vscode-concourse/src/main/resources/desc/PoolSource/username.md @@ -0,0 +1,2 @@ +*Optional.* Username for HTTP(S) auth when pulling/pushing. +This is needed when only HTTP/HTTPS protocol for git is available (which does not support private key auth) and auth is required. diff --git a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java index 42e140bcd..643fe9a70 100644 --- a/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java +++ b/vscode-extensions/vscode-concourse/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java @@ -1499,6 +1499,110 @@ public class ConcourseEditorTest { ); } + @Test public void poolResourceSourceReconcileAndHovers() throws Exception { + Editor editor; + + editor = harness.newEditor( + "resources:\n" + + "- name: swimming-pool\n" + + " type: pool\n" + + " source:\n" + + " private_key: stuff" + ); + editor.assertProblems( + "private_key: stuff|[branch, pool, uri] are required" + ); + + editor = harness.newEditor( + "resources:\n" + + "- name: the--locks\n" + + " type: pool\n" + + " source:\n" + + " uri: git@github.com:concourse/locks.git\n" + + " branch: master\n" + + " pool: aws\n" + + " private_key: |\n" + + " -----BEGIN RSA PRIVATE KEY-----\n" + + " MIIEowIBAAKCAQEAtCS10/f7W7lkQaSgD/mVeaSOvSF9ql4hf/zfMwfVGgHWjj+W\n" + + " ...\n" + + " DWiJL+OFeg9kawcUL6hQ8JeXPhlImG6RTUffma9+iGQyyBMCGd1l\n" + + " -----END RSA PRIVATE KEY-----\n" + + " username: jonhsmith\n" + + " password: his-password\n" + + " retry_delay: retry-after\n" + ); + System.out.println(editor.getRawText()); + editor.assertProblems( + "retry-after|'Duration'" + ); + + editor.assertHoverContains("uri", "The location of the repository."); + editor.assertHoverContains("branch", "The branch to track"); + editor.assertHoverContains("pool", 2, "The logical name of your pool of things to lock"); + editor.assertHoverContains("private_key", "Private key to use when pulling/pushing"); + editor.assertHoverContains("username", "Username for HTTP(S) auth"); + editor.assertHoverContains("password", "Password for HTTP(S) auth "); + editor.assertHoverContains("retry_delay", "how long to wait until retrying"); + } + + @Test public void poolResourceGetParamsReconcileAndHovers() throws Exception { + Editor editor; + + editor = harness.newEditor( + "resources:\n" + + "- name: my-locks\n" + + " type: pool\n" + + "jobs:\n" + + "- name: a-job\n" + + " plan:\n" + + " - get: my-locks\n" + + " params:\n" + + " no-params-expected: bad" + ); + + editor.assertProblems( + "no-params-expected|Unknown property" + ); + } + + @Test public void poolResourcePutParamsReconcileAndHovers() throws Exception { + Editor editor; + + editor = harness.newEditor( + "resources:\n" + + "- name: my-locks\n" + + " type: pool\n" + + "jobs:\n" + + "- name: a-job\n" + + " plan:\n" + + " - put: my-locks\n" + + " params:\n" + + " acquire: should-acquire\n" + + " claim: a-specific-lock\n" + + " release: path/to/lock\n" + + " add: path/to/lock\n" + + " add_claimed: path/to/lock\n" + + " remove: path/to/lock" + ); + + editor.assertProblems( + "acquire|Only one of", + "should-acquire|'boolean'", + "claim|Only one of", + "release|Only one of", + "add|Only one of", + "add_claimed|Only one of", + "remove|Only one of" + ); + + editor.assertHoverContains("acquire", "attempt to move a randomly chosen lock"); + editor.assertHoverContains("claim", "the specified lock from the pool will be acquired"); + editor.assertHoverContains("release", "release the lock"); + editor.assertHoverContains("add", "add a new lock to the pool in the unclaimed state"); + editor.assertHoverContains("add_claimed", "in the *claimed* state"); + editor.assertHoverContains("remove", "remove the given lock from the pool"); + } + @Test public void gotoResourceDefinition() throws Exception { Editor editor = harness.newEditor(