diff --git a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java index 9708c6121..840697041 100644 --- a/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java +++ b/headless-services/concourse-language-server/src/main/java/org/springframework/ide/vscode/concourse/PipelineYmlSchema.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016 Pivotal, Inc. + * Copyright (c) 2016, 2023 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -502,6 +502,63 @@ public class PipelineYmlSchema implements YamlSchema { YType t_group_name_def= f.yatomic("Group Name") .parseWith(ValueParsers.NE_STRING); + + /** + * VAR_SOURCE definition + */ + YBeanType t_var_source_type = f.ybean("VarSource"); + addProp(t_var_source_type, "name", t_ne_string).isPrimary(true); + addProp(t_var_source_type, "type", f.yenum("VarSourceTypes", "vault", "ssm", "dummy", "secretmanager")).isRequired(true); + addProp(t_var_source_type, "config", f.contextAware("VarSourceConfig", (dc) -> { + YamlPath path = dc.getPath(); + if (path != null) { + YamlFileAST root = asts.getSafeAst(dc.getDocument()); + if (root!=null) { + String value = NodeUtil.asScalar(path.dropLast().append(YamlPathSegment.valueAt("type")).traverseToNode(root)); + switch (value) { + case "vault": + YBeanType vaultConfig = f.ybean("VaultConfig"); + addProp(vaultConfig, "uri", t_ne_string).isPrimary(true); + addProp(vaultConfig, "ca_cert", t_string); + addProp(vaultConfig, "path_prefix", t_string); + addProp(vaultConfig, "lookup_templates", f.yseq(t_string)); + addProp(vaultConfig, "shared_path", t_string); + addProp(vaultConfig, "namespace", t_string); + addProp(vaultConfig, "client_cert", t_string); + addProp(vaultConfig, "client_key", t_string); + addProp(vaultConfig, "client_name", t_string); + addProp(vaultConfig, "insecure_skip_verify", t_boolean); + addProp(vaultConfig, "client_token", t_string); + addProp(vaultConfig, "auth_backend", t_string); + addProp(vaultConfig, "auth_params", f.ymap(t_ne_string, t_string)); + addProp(vaultConfig, "auth_max_ttl", t_duration); + addProp(vaultConfig, "auth_retry_max", t_duration); + addProp(vaultConfig, "auth_retry_initial", t_duration); + return vaultConfig; + case "ssm": + YBeanType ssmConfig = f.ybean("SSMConfig"); + addProp(ssmConfig, "region", t_string).isPrimary(true); + return ssmConfig; + case "dummy": + YBeanType dummyConfig = f.ybean("DummyConfig"); + addProp(dummyConfig, "vars", t_any).isPrimary(true); + return dummyConfig; + case "secretmanager": + YBeanType smcConfig = f.ybean("SecretManagerConfig"); + addProp(smcConfig, "aws-secretsmanager-region", t_ne_string).isPrimary(true); + addProp(smcConfig, "aws-secretsmanager-access-key", t_ne_string); + addProp(smcConfig, "aws-secretsmanager-secret-key", t_ne_string); + addProp(smcConfig, "aws-secretsmanager-session-token", t_ne_string); + addProp(smcConfig, "aws-secretsmanager-pipeline-secret-template", t_string); + addProp(smcConfig, "aws-secretsmanager-team-secret-template", t_string); + return smcConfig; + default: + return null; + } + } + } + return null; + }).treatAsBean()).isRequired(true); AbstractType group = f.ybean("Group"); addProp(group, "name", t_group_name_def).isPrimary(true); @@ -520,6 +577,7 @@ public class PipelineYmlSchema implements YamlSchema { AbstractType t_groups = f.yseq(group).require(models::jobAssignmentIsComplete); addProp(TOPLEVEL_TYPE, "resources", t_resources); addProp(TOPLEVEL_TYPE, "jobs", t_jobs); + addProp(TOPLEVEL_TYPE, "var_sources", f.yseq(t_var_source_type)); addProp(TOPLEVEL_TYPE, "resource_types", t_resourceTypes); addProp(TOPLEVEL_TYPE, "groups", t_groups); addProp(TOPLEVEL_TYPE, "display", t_display); diff --git a/headless-services/concourse-language-server/src/main/resources/desc/DummyConfig/vars.md b/headless-services/concourse-language-server/src/main/resources/desc/DummyConfig/vars.md new file mode 100644 index 000000000..c55af4a15 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/DummyConfig/vars.md @@ -0,0 +1 @@ +*Required.* A mapping of **var** name to **var** value. An arbitrary object representing key-value definitions for **((vars))**. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/SSMConfig/region.md b/headless-services/concourse-language-server/src/main/resources/desc/SSMConfig/region.md new file mode 100644 index 000000000..0f7734831 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/SSMConfig/region.md @@ -0,0 +1 @@ +*Required.* The AWS region to read secrets from. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-access-key.md b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-access-key.md new file mode 100644 index 000000000..d27ea8554 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-access-key.md @@ -0,0 +1 @@ +*Optional.* A valid AWS access key. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-pipeline-secret-template.md b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-pipeline-secret-template.md new file mode 100644 index 000000000..7a8d1574d --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-pipeline-secret-template.md @@ -0,0 +1 @@ +*Optional.* The base path used when attempting to locate a pipeline-level secret. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-region.md b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-region.md new file mode 100644 index 000000000..b347e7389 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-region.md @@ -0,0 +1 @@ +*Required.* The AWS region that requests to Secrets Manager will be sent to. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-secret-key.md b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-secret-key.md new file mode 100644 index 000000000..f593b8c38 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-secret-key.md @@ -0,0 +1 @@ +*Optional.* The secret key that corresponds to the access key defined above. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-session-token.md b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-session-token.md new file mode 100644 index 000000000..a72497ac2 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-session-token.md @@ -0,0 +1 @@ +*Optional.* A valid AWS session token. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-team-secret-template.md b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-team-secret-template.md new file mode 100644 index 000000000..f5d203913 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/SecretManagerConfig/aws-secretsmanager-team-secret-template.md @@ -0,0 +1 @@ +*Optional.* The base path used when attempting to locate a team-level secret. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VarSource/config.md b/headless-services/concourse-language-server/src/main/resources/desc/VarSource/config.md new file mode 100644 index 000000000..f86964411 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VarSource/config.md @@ -0,0 +1,5 @@ +*Required.* Depending on the chosen `type` corresponding config: +- The **Vault** for configuring a [Vault](https://www.vaultproject.io/) server as a **((var))** source. +- The **SSM** for configuring an [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/) in a single region as a **((var))** source. +- The **Dummy** for configuring a static map of vars to values. This is really only useful if you have no better alternative for credential management but still have sensitive values that you would like to redact them from build output. +- The **Secret Manager** for configuring integration with [AWS Secrets Manager for credential management](https://concourse-ci.org/aws-asm-credential-manager.html) \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VarSource/name.md b/headless-services/concourse-language-server/src/main/resources/desc/VarSource/name.md new file mode 100644 index 000000000..7b0c306e2 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VarSource/name.md @@ -0,0 +1 @@ +*Required.* The name of the **((var))** source. This should be short and simple. This name will be referenced **((var))** [syntax](https://concourse-ci.org/vars.html#var-syntax) throughout the config. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VarSource/type.md b/headless-services/concourse-language-server/src/main/resources/desc/VarSource/type.md new file mode 100644 index 000000000..3e4782940 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VarSource/type.md @@ -0,0 +1,5 @@ +*Required.* Expected one of: +- `vault` type supports configuring a [Vault](https://www.vaultproject.io/) server as a **((var))** source. +- `ssm` type supports configuring an [AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/) in a single region as a **((var))** source. +- `dummy` type supports configuring a static map of vars to values. This is really only useful if you have no better alternative for credential management but still have sensitive values that you would like to redact them from build output. +- `secretmanager` type supports integration with [AWS Secrets Manager for credential management](https://concourse-ci.org/aws-asm-credential-manager.html) \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_backend.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_backend.md new file mode 100644 index 000000000..d7a51e3c2 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_backend.md @@ -0,0 +1,3 @@ +*Optional.* Authenticate using an auth backend, e.g. cert or approle. + +See [Using the approle auth backend](https://concourse-ci.org/vault-credential-manager.html#vault-approle-auth) or [Using the cert auth backend](https://concourse-ci.org/vault-credential-manager.html#vault-cert-auth) for more information. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_max_ttl.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_max_ttl.md new file mode 100644 index 000000000..3c069dc8e --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_max_ttl.md @@ -0,0 +1 @@ +*Optional.* Maximum duration to elapse before forcing the client to log in again. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_params.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_params.md new file mode 100644 index 000000000..459227ffa --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_params.md @@ -0,0 +1,3 @@ +*Optional.* A key-value map of parameters to pass during authentication. + +See [Using the approle auth backend](https://concourse-ci.org/vault-credential-manager.html#vault-approle-auth) for more information. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_retry_initial.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_retry_initial.md new file mode 100644 index 000000000..8492001d8 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_retry_initial.md @@ -0,0 +1 @@ +*Optional.* When retrying during authentication, start with this retry interval. The interval will increase exponentially until `auth_retry_max` is reached. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_retry_max.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_retry_max.md new file mode 100644 index 000000000..f7a17a934 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/auth_retry_max.md @@ -0,0 +1 @@ +*Optional.* When failing to authenticate, give up after this amount of time. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/ca_cert.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/ca_cert.md new file mode 100644 index 000000000..27f15016d --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/ca_cert.md @@ -0,0 +1 @@ +*Optional.* The PEM encoded contents of a CA certificate to use when connecting to the API. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_cert.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_cert.md new file mode 100644 index 000000000..ed38f8b89 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_cert.md @@ -0,0 +1,3 @@ +*Optional.* A PEM encoded client certificate, for use with TLS based auth. + +See [Using the cert auth backend](https://concourse-ci.org/vault-credential-manager.html#vault-cert-auth) for more information. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_key.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_key.md new file mode 100644 index 000000000..41109b3a1 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_key.md @@ -0,0 +1,3 @@ +*Optional.* A PEM encoded client key, for use with TLS based auth. + +See [Using the cert auth backend](https://concourse-ci.org/vault-credential-manager.html#vault-cert-auth) for more information. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_name.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_name.md new file mode 100644 index 000000000..ba9e81b02 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_name.md @@ -0,0 +1 @@ +*Optional.* The expected name of the server when connecting through TLS. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_token.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_token.md new file mode 100644 index 000000000..125ae4a6b --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/client_token.md @@ -0,0 +1,3 @@ +*Optional.* Authenticate via a periodic client token. + +See [Using a periodic token](https://concourse-ci.org/vault-credential-manager.html#vault-periodic-token) for more information. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/insecure_skip_verify.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/insecure_skip_verify.md new file mode 100644 index 000000000..5075762bd --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/insecure_skip_verify.md @@ -0,0 +1 @@ +*Optional.* Skip TLS validation. Not recommended. Don't do it. No really, don't. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/lookup_templates.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/lookup_templates.md new file mode 100644 index 000000000..bb1b61fc7 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/lookup_templates.md @@ -0,0 +1,5 @@ +*Optional.* Default `["/{{.Team}}/{{.Pipeline}}/{{.Secret}}", "/{{.Team}}/{{.Secret}}"]`. + +A list of path templates to be expanded in a team and pipeline context subject to the `path_prefix` and `namespace`. + +See [Changing the path templates](https://concourse-ci.org/vault-credential-manager.html#vault-lookup-templates) for more information. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/namespace.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/namespace.md new file mode 100644 index 000000000..cd5fa4de7 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/namespace.md @@ -0,0 +1 @@ +*Optional.* A [Vault namespace](https://www.vaultproject.io/docs/enterprise/namespaces/index.html) to operate under. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/path_prefix.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/path_prefix.md new file mode 100644 index 000000000..c59678d1b --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/path_prefix.md @@ -0,0 +1,3 @@ +*Optional.* Default `/concourse`. A prefix under which to look for all credential values. + +See [Changing the path prefix](https://concourse-ci.org/vault-credential-manager.html#vault-path-prefix) for more information. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/shared_path.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/shared_path.md new file mode 100644 index 000000000..eb8546304 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/shared_path.md @@ -0,0 +1,3 @@ +*Optional.* An additional path under which credentials will be looked up. + +See [Configuring a shared path](https://concourse-ci.org/vault-credential-manager.html#vault-shared-path) for more information. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/uri.md b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/uri.md new file mode 100644 index 000000000..91f6a4c64 --- /dev/null +++ b/headless-services/concourse-language-server/src/main/resources/desc/VaultConfig/uri.md @@ -0,0 +1 @@ +*Required.* The URL of the Vault API. \ No newline at end of file diff --git a/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java b/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java index 1b550fb64..65e07ae12 100644 --- a/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java +++ b/headless-services/concourse-language-server/src/test/java/org/springframework/ide/vscode/concourse/ConcourseEditorTest.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2016, 2022 Pivotal, Inc. + * Copyright (c) 2016, 2023 Pivotal, Inc. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -1113,6 +1113,12 @@ public class ConcourseEditorTest { "resources:\n" + "- name: $1\n" + " type: $2<*>" + , // --------------- + "var_sources:\n" + + "- name: $1\n" + + " type: $2\n" + + " config:\n" + + " $3<*>" ); editor = harness.newEditor("rety<*>"); @@ -4689,6 +4695,7 @@ public class ConcourseEditorTest { "← groups", "← jobs", "← resource_types", + "← var_sources", "← - Resource Snippet", // For the 'next job' context "← - name" @@ -4949,6 +4956,7 @@ public class ConcourseEditorTest { "← groups", "← resource_types", "← resources", + "← var_sources", "← - Job Snippet", "← - name" ); @@ -5443,6 +5451,7 @@ public class ConcourseEditorTest { "groups", "jobs", "resource_types", + "var_sources", "→ type", "- Resource Snippet", "- name" @@ -6811,6 +6820,178 @@ public class ConcourseEditorTest { editor.assertCompletionLabels(c -> c.getLabel().startsWith("cache"), "cache", "cache_from", "cache_tag"); } } + + @Test + void var_source_AttributeHovers() throws Exception { + Editor editor = harness.newEditor( + "var_sources:\n" + + "- name: sts4\n" + + " type: ssm\n" + + " config:\n" + + " region: east\n" + ); + editor.assertProblems(); + + editor.assertHoverContains("name", "The name of the **((var))** source"); + editor.assertHoverContains("type", "Expected one of:"); + editor.assertHoverContains("config", "Depending on the chosen `type` corresponding config:"); + } + + @Test + void var_source_AttributeReconcile() throws Exception { + Editor editor = harness.newEditor( + "var_sources:\n" + + "- name: " + ); + editor.assertProblems( + "-|[config, type] are required", + "|String should not be empty" + ); + + editor = harness.newEditor( + "var_sources:\n" + + "- type: blah" + ); + editor.assertProblems( + "-|[config, name] are required", + "blah|Valid values are: [dummy, secretmanager, ssm, vault]" + ); + } + + @Test + void var_source_SSMConfig_Attrs_Hovers() throws Exception { + Editor editor = harness.newEditor( + "var_sources:\n" + + "- name: sts4\n" + + " type: ssm\n" + + " config:\n" + + " region: east\n" + ); + editor.assertProblems(); + + editor.assertHoverContains("region", "The AWS region to read secrets from."); + } + + @Test + void var_source_DummyConfig_Attrs_Hovers() throws Exception { + Editor editor = harness.newEditor( + "var_sources:\n" + + "- name: sts4\n" + + " type: dummy\n" + + " config:\n" + + " vars: east\n" + ); + + editor.assertProblems(); + + editor.assertHoverContains("vars", "A mapping of **var** name to **var** value."); + } + + @Test + void var_source_SecretManagerConfig_Attrs_Hovers() throws Exception { + Editor editor = harness.newEditor( + "var_sources:\n" + + "- name: sts4\n" + + " type: secretmanager\n" + + " config:\n" + + " aws-secretsmanager-access-key: access-key\n" + + " aws-secretsmanager-secret-key: secret-key\n" + + " aws-secretsmanager-session-token: token\n" + + " aws-secretsmanager-region: region\n" + + " aws-secretsmanager-pipeline-secret-template: pipeline\n" + + " aws-secretsmanager-team-secret-template: team\n" + ); + + editor.assertProblems(); + + editor.assertHoverContains("aws-secretsmanager-access-key", "A valid AWS access key."); + editor.assertHoverContains("aws-secretsmanager-secret-key", "The secret key that corresponds to the access key defined above."); + editor.assertHoverContains("aws-secretsmanager-session-token", "A valid AWS session token."); + editor.assertHoverContains("aws-secretsmanager-region", "The AWS region that requests to Secrets Manager will be sent to."); + editor.assertHoverContains("aws-secretsmanager-pipeline-secret-template", "The base path used when attempting to locate a pipeline-level secret."); + editor.assertHoverContains("aws-secretsmanager-team-secret-template", "The base path used when attempting to locate a team-level secret."); + } + + @Test + void var_source_SecretManagerConfig_Attrs_Reconcile() throws Exception { + Editor editor = harness.newEditor( + "var_sources:\n" + + "- name: sts4\n" + + " type: secretmanager\n" + + " config:\n" + + " aws-secretsmanager-access-key: access-key\n" + ); + + editor.assertProblems( + "config|'aws-secretsmanager-region' is required" + ); + } + + @Test + void var_source_VaultConfig_Attrs_Hovers() throws Exception { + Editor editor = harness.newEditor( + "var_sources:\n" + + "- name: sts4\n" + + " type: vault\n" + + " config:\n" + + " uri: some_uri\n" + + " auth_backend: backend\n" + + " auth_max_ttl: 10s\n" + + " auth_params: \n" + + " p1: v1\n" + + " p2: v2\n" + + " auth_retry_initial: 1s\n" + + " auth_retry_max: 60s\n" + + " ca_cert: ca\n" + + " client_cert: client\n" + + " client_key: client-key\n" + + " client_name: client-name\n" + + " client_token: client-token\n" + + " insecure_skip_verify: true\n" + + " lookup_templates:\n" + + " - t1\n" + + " - t2\n" + + " namespace: awesomes\n" + + " path_prefix: prefix\n" + + " shared_path: shared\n" + ); + + editor.assertProblems(); + + editor.assertHoverContains("uri", "The URL of the Vault API."); + editor.assertHoverContains("auth_backend", "Authenticate using an auth backend, e.g. cert or approle."); + editor.assertHoverContains("auth_max_ttl", "Maximum duration to elapse before forcing the client to log in again."); + editor.assertHoverContains("auth_params", "A key-value map of parameters to pass during authentication."); + editor.assertHoverContains("auth_retry_initial", "When retrying during authentication, start with this retry interval."); + editor.assertHoverContains("auth_retry_max", "When failing to authenticate, give up after this amount of time."); + + editor.assertHoverContains("ca_cert", "The PEM encoded contents of a CA certificate to use when connecting to the API."); + editor.assertHoverContains("client_cert", "A PEM encoded client certificate, for use with TLS based auth."); + editor.assertHoverContains("client_key", "A PEM encoded client key, for use with TLS based auth."); + editor.assertHoverContains("client_name", "The expected name of the server when connecting through TLS."); + editor.assertHoverContains("client_token", "Authenticate via a periodic client token."); + editor.assertHoverContains("insecure_skip_verify", "Skip TLS validation. Not recommended. Don't do it. No really, don't."); + editor.assertHoverContains("lookup_templates", "A list of path templates to be expanded in a team and pipeline context subject to the `path_prefix` and `namespace`."); + editor.assertHoverContains("namespace", "Vault namespace"); + editor.assertHoverContains("path_prefix", "A prefix under which to look for all credential values."); + editor.assertHoverContains("shared_path", "An additional path under which credentials will be looked up."); + } + + @Test + void var_source_VaultConfig_Attrs_Reconcile() throws Exception { + Editor editor = harness.newEditor( + "var_sources:\n" + + "- name: sts4\n" + + " type: vault\n" + + " config:\n" + + " namespace: awesome\n" + ); + + editor.assertProblems( + "config|'uri' is required" + ); + } + //////////////////////////////////////////////////////////////////////////////