diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index 519e7f9b..00000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,56 +0,0 @@ -version: 2 - -jobs: - build: - docker: - - image: circleci/openjdk:8u151-jdk - environment: - JAVA_TOOL_OPTIONS: "-Xms512m -Xmx768m" - TERM: dumb - branches: - ignore: - - gh-pages # list of branches to ignore - steps: - - setup_remote_docker - - checkout - - restore_cache: - key: sc-vault-{{ .Branch }} - - run: - name: "Download dependencies" - command: ./mvnw -s .settings.xml -B -U --fail-never dependency:go-offline || true - - run: - name: "Download Vault" - command: src/test/bash/install_vault.sh - - save_cache: - key: sc-vault-{{ .Branch }} - paths: - - ~/.m2 - - "download" - - run: - name: "Create Certificates" - command: src/test/bash/create_certificates.sh - - run: - name: "Starting Vault" - command: src/test/bash/local_run_vault.sh - background: true - - run: - name: "Running build" - command: ./mvnw -s .settings.xml clean org.jacoco:jacoco-maven-plugin:prepare-agent install install -U -P sonar -nsu -B -Dmaven.test.redirectTestOutputToFile=true -Dorg.slf4j.simpleLogger.log.org.apache.maven.cli.transfer.Slf4jMavenTransferListener=warn - - run: - name: "Starting Vault" - command: pkill vault - when: always - - run: - name: "Aggregate test results" - when: always - command: | - mkdir -p junit/ - find . -type f -regex ".*/target/.*-reports/.*" -exec cp {} junit/ \; - find . -type f -regex ".*/build/test-results/.*" -exec cp {} junit/ \; - bash <(curl -s https://codecov.io/bash) - - store_artifacts: - path: junit/ - destination: artifacts - - store_test_results: - path: junit/ - destination: testartifacts diff --git a/.editorconfig b/.editorconfig deleted file mode 100644 index 52e6a1af..00000000 --- a/.editorconfig +++ /dev/null @@ -1,24 +0,0 @@ -root = true - -[*.java] -indent_style = tab -indent_size = 4 -continuation_indent_size = 8 - -[*.groovy] -indent_style = tab -indent_size = 4 -continuation_indent_size = 8 - -[*.xml] -indent_style = tab -indent_size = 4 -continuation_indent_size = 8 - -[*.yml] -indent_style = space -indent_size = 2 - -[*.yaml] -indent_style = space -indent_size = 2 \ No newline at end of file diff --git a/.flattened-pom.xml b/.flattened-pom.xml new file mode 100644 index 00000000..991b3851 --- /dev/null +++ b/.flattened-pom.xml @@ -0,0 +1,163 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-build + 4.1.0-SNAPSHOT + + + org.springframework.cloud + spring-cloud-vault-parent + 4.1.0-SNAPSHOT + pom + Spring Cloud Vault + Configuration Integration with HashiCorp Vault + https://spring.io/spring-cloud/spring-cloud-vault-parent + + Pivotal Software, Inc. + https://www.spring.io + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + Copyright 2014-2021 the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. + + See the License for the specific language governing permissions and + limitations under the License. + + + + + dsyer + Dave Syer + dsyer at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + sgibb + Spencer Gibb + sgibb at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + mgrzejszczak + Marcin Grzejszczak + mgrzejszczak at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + rbaxter + Ryan Baxter + rbaxter at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + omaciaszeksharma + Olga Maciaszek-Sharma + omaciaszeksharma at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + + scm:git:git://github.com/spring-cloud/spring-cloud-vault.git + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-vault.git + https://github.com/spring-cloud/spring-cloud-vault + + + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + + org.hibernate.validator + hibernate-validator + 8.0.0.Final + provided + + + org.springframework.boot + spring-boot-autoconfigure + 3.2.0-SNAPSHOT + provided + + + org.springframework.boot + spring-boot-starter + 3.2.0-SNAPSHOT + provided + + + + + spring + + true + + + + + false + + + true + + spring-snapshots + Spring Snapshots + https://repo.spring.io/snapshot + + + + false + + spring-milestones + Spring Milestones + https://repo.spring.io/libs-milestone-local + + + + false + + spring-releases + Spring Releases + https://repo.spring.io/release + + + + + diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index d3204a48..00000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -title: '' -labels: waiting-for-triage -assignees: '' - ---- - -**Describe the bug** -Please provide details of the problem, including the version of Spring Cloud that you -are using. - -**Sample** -If possible, please provide a test case or sample application that reproduces -the problem. This makes it much easier for us to diagnose the problem and to verify that -we have fixed it. \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index b2e33c5f..00000000 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: waiting-for-triage -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. \ No newline at end of file diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml new file mode 100644 index 00000000..463218ed --- /dev/null +++ b/.github/workflows/deploy-docs.yml @@ -0,0 +1,53 @@ +name: Deploy Docs +run-name: ${{ format('{0} ({1})', github.workflow, github.event.inputs.build-refname || 'all') }} +on: + workflow_dispatch: + inputs: + build-refname: + description: Enter git refname to build (e.g., 5.7.x). + required: false + push: + branches: docs-build +env: + GRADLE_ENTERPRISE_SECRET_ACCESS_KEY: ${{ secrets.GRADLE_ENTERPRISE_SECRET_ACCESS_KEY }} +permissions: + contents: write +jobs: + build: + if: github.repository_owner == 'spring-cloud' + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + fetch-depth: 5 + - name: Set up JDK 17 + uses: actions/setup-java@v3 + with: + java-version: '17' + distribution: 'temurin' + - name: Set up refname build + if: github.event.inputs.build-refname + run: | + git fetch --depth 1 https://github.com/$GITHUB_REPOSITORY ${{ github.event.inputs.build-refname }} + export BUILD_REFNAME=${{ github.event.inputs.build-refname }} + echo "BUILD_REFNAME=$BUILD_REFNAME" >> $GITHUB_ENV + export BUILD_VERSION=$(git cat-file --textconv FETCH_HEAD:pom.xml | python3 -c "import xml.etree.ElementTree as xml; from sys import stdin; print(xml.parse(stdin).getroot().find('{http://maven.apache.org/POM/4.0.0}version').text)") + echo BUILD_VERSION=$BUILD_VERSION >> $GITHUB_ENV + - name: Run Antora + run: | + ./mvnw --no-transfer-progress -B antora + - name: Publish Docs + uses: spring-io/spring-doc-actions/rsync-antora-reference@v0.0.11 + with: + docs-username: ${{ secrets.DOCS_USERNAME }} + docs-host: ${{ secrets.DOCS_HOST }} + docs-ssh-key: ${{ secrets.DOCS_SSH_KEY }} + docs-ssh-host-key: ${{ secrets.DOCS_SSH_HOST_KEY }} + site-path: target/antora/site + - name: Bust Cloudflare Cache + uses: spring-io/spring-doc-actions/bust-cloudflare-antora-cache@v0.0.11 + with: + context-root: spring-cloud-vault + cloudflare-zone-id: ${{ secrets.CLOUDFLARE_ZONE_ID }} + cloudflare-cache-token: ${{ secrets.CLOUDFLARE_CACHE_TOKEN }} diff --git a/.gitignore b/.gitignore index e155f0dc..6be8a4a1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,28 +1,22 @@ -*~ -#* -*# -.#* -.classpath -.project -.settings/ -.springBeans target/ -bin/ -_site/ -.idea +.settings/ +.project +.classpath +*.orig +.springBeans +.factorypath +.sts4-cache +.ant-targets-build.xml +src/ant/.ant-targets-upload-dist.xml +*.sonar4clipse* +.DS_Store *.iml *.ipr *.iws -.factorypath -download/ -/vault/ -/consul/ -/rabbitmq/ -work -build/ -pom.xml.releaseBackup -.flattened-pom.xml -release.properties -.vscode/ -plugins/ - +/.idea/ +*.graphml +node +node_modules +build +package.json +package-lock.json diff --git a/.mvn/jvm.config b/.mvn/jvm.config new file mode 100644 index 00000000..0e7dabef --- /dev/null +++ b/.mvn/jvm.config @@ -0,0 +1 @@ +-Xmx1024m -XX:CICompilerCount=1 -XX:TieredStopAtLevel=1 -Djava.security.egd=file:/dev/./urandom \ No newline at end of file diff --git a/.mvn/wrapper/MavenWrapperDownloader.java b/.mvn/wrapper/MavenWrapperDownloader.java new file mode 100644 index 00000000..b901097f --- /dev/null +++ b/.mvn/wrapper/MavenWrapperDownloader.java @@ -0,0 +1,117 @@ +/* + * Copyright 2007-present the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.net.*; +import java.io.*; +import java.nio.channels.*; +import java.util.Properties; + +public class MavenWrapperDownloader { + + private static final String WRAPPER_VERSION = "0.5.6"; + /** + * Default URL to download the maven-wrapper.jar from, if no 'downloadUrl' is provided. + */ + private static final String DEFAULT_DOWNLOAD_URL = "https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/" + + WRAPPER_VERSION + "/maven-wrapper-" + WRAPPER_VERSION + ".jar"; + + /** + * Path to the maven-wrapper.properties file, which might contain a downloadUrl property to + * use instead of the default one. + */ + private static final String MAVEN_WRAPPER_PROPERTIES_PATH = + ".mvn/wrapper/maven-wrapper.properties"; + + /** + * Path where the maven-wrapper.jar will be saved to. + */ + private static final String MAVEN_WRAPPER_JAR_PATH = + ".mvn/wrapper/maven-wrapper.jar"; + + /** + * Name of the property which should be used to override the default download url for the wrapper. + */ + private static final String PROPERTY_NAME_WRAPPER_URL = "wrapperUrl"; + + public static void main(String args[]) { + System.out.println("- Downloader started"); + File baseDirectory = new File(args[0]); + System.out.println("- Using base directory: " + baseDirectory.getAbsolutePath()); + + // If the maven-wrapper.properties exists, read it and check if it contains a custom + // wrapperUrl parameter. + File mavenWrapperPropertyFile = new File(baseDirectory, MAVEN_WRAPPER_PROPERTIES_PATH); + String url = DEFAULT_DOWNLOAD_URL; + if(mavenWrapperPropertyFile.exists()) { + FileInputStream mavenWrapperPropertyFileInputStream = null; + try { + mavenWrapperPropertyFileInputStream = new FileInputStream(mavenWrapperPropertyFile); + Properties mavenWrapperProperties = new Properties(); + mavenWrapperProperties.load(mavenWrapperPropertyFileInputStream); + url = mavenWrapperProperties.getProperty(PROPERTY_NAME_WRAPPER_URL, url); + } catch (IOException e) { + System.out.println("- ERROR loading '" + MAVEN_WRAPPER_PROPERTIES_PATH + "'"); + } finally { + try { + if(mavenWrapperPropertyFileInputStream != null) { + mavenWrapperPropertyFileInputStream.close(); + } + } catch (IOException e) { + // Ignore ... + } + } + } + System.out.println("- Downloading from: " + url); + + File outputFile = new File(baseDirectory.getAbsolutePath(), MAVEN_WRAPPER_JAR_PATH); + if(!outputFile.getParentFile().exists()) { + if(!outputFile.getParentFile().mkdirs()) { + System.out.println( + "- ERROR creating output directory '" + outputFile.getParentFile().getAbsolutePath() + "'"); + } + } + System.out.println("- Downloading to: " + outputFile.getAbsolutePath()); + try { + downloadFileFromURL(url, outputFile); + System.out.println("Done"); + System.exit(0); + } catch (Throwable e) { + System.out.println("- Error downloading"); + e.printStackTrace(); + System.exit(1); + } + } + + private static void downloadFileFromURL(String urlString, File destination) throws Exception { + if (System.getenv("MVNW_USERNAME") != null && System.getenv("MVNW_PASSWORD") != null) { + String username = System.getenv("MVNW_USERNAME"); + char[] password = System.getenv("MVNW_PASSWORD").toCharArray(); + Authenticator.setDefault(new Authenticator() { + @Override + protected PasswordAuthentication getPasswordAuthentication() { + return new PasswordAuthentication(username, password); + } + }); + } + URL website = new URL(urlString); + ReadableByteChannel rbc; + rbc = Channels.newChannel(website.openStream()); + FileOutputStream fos = new FileOutputStream(destination); + fos.getChannel().transferFrom(rbc, 0, Long.MAX_VALUE); + fos.close(); + rbc.close(); + } + +} diff --git a/.mvn/wrapper/maven-wrapper.jar b/.mvn/wrapper/maven-wrapper.jar index 5fd4d502..2cc7d4a5 100644 Binary files a/.mvn/wrapper/maven-wrapper.jar and b/.mvn/wrapper/maven-wrapper.jar differ diff --git a/.mvn/wrapper/maven-wrapper.properties b/.mvn/wrapper/maven-wrapper.properties index c3150437..642d572c 100644 --- a/.mvn/wrapper/maven-wrapper.properties +++ b/.mvn/wrapper/maven-wrapper.properties @@ -1 +1,2 @@ -distributionUrl=https://repo1.maven.org/maven2/org/apache/maven/apache-maven/3.5.0/apache-maven-3.5.0-bin.zip +distributionUrl=https://repo.maven.apache.org/maven2/org/apache/maven/apache-maven/3.6.3/apache-maven-3.6.3-bin.zip +wrapperUrl=https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar diff --git a/.sdkmanrc b/.sdkmanrc deleted file mode 100644 index 415f9083..00000000 --- a/.sdkmanrc +++ /dev/null @@ -1,3 +0,0 @@ -# Enable auto-env through the sdkman_auto_env config -# Add key=value pairs of SDKs to use below -java=17.0.1-tem diff --git a/.settings.xml b/.settings.xml deleted file mode 100644 index 171351c0..00000000 --- a/.settings.xml +++ /dev/null @@ -1,62 +0,0 @@ - - - - - repo.spring.io - ${env.CI_DEPLOY_USERNAME} - ${env.CI_DEPLOY_PASSWORD} - - - - - spring - - true - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/libs-snapshot-local - - true - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - - - diff --git a/CODE_OF_CONDUCT.adoc b/CODE_OF_CONDUCT.adoc deleted file mode 100644 index 33ae7bc9..00000000 --- a/CODE_OF_CONDUCT.adoc +++ /dev/null @@ -1,27 +0,0 @@ -= Contributor Code of Conduct - -As contributors and maintainers of this project, and in the interest of fostering an open and welcoming community, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities. - -We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, religion, or nationality. - -Examples of unacceptable behavior by participants include: - -* The use of sexualized language or imagery -* Personal attacks -* Trolling or insulting/derogatory comments -* Public or private harassment -* Publishing other's private information, such as physical or electronic addresses, - without explicit permission -* Other unethical or unprofessional conduct - -Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. - -By adopting this Code of Conduct, project maintainers commit themselves to fairly and consistently applying these principles to every aspect of managing this project. Project maintainers who do not follow or enforce the Code of Conduct may be permanently removed from the project team. - -This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting a project maintainer at spring-code-of-conduct@pivotal.io. -All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. -Maintainers are obligated to maintain confidentiality with regard to the reporter of an incident. - -This Code of Conduct is adapted from the https://contributor-covenant.org[Contributor Covenant], version 1.3.0, available at https://contributor-covenant.org/version/1/3/0/[contributor-covenant.org/version/1/3/0/]. \ No newline at end of file diff --git a/LICENSE.txt b/LICENSE.txt deleted file mode 100644 index 62589edd..00000000 --- a/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/README.adoc b/README.adoc index 813174ac..aabf34c6 100644 --- a/README.adoc +++ b/README.adoc @@ -1,641 +1,23 @@ -//// -DO NOT EDIT THIS FILE. IT WAS GENERATED. -Manual changes to this file will be lost when it is generated again. -Edit the files in the src/main/asciidoc/ directory instead. -//// += Spring Cloud Vault Docs Build +You're currently viewing the Antora playbook branch. +The playbook branch hosts the docs build that is used to build and publish the production docs site. -:docs: https://cloud.spring.io/spring-cloud-vault/spring-cloud-vault.html +The Spring Cloud Vault reference docs are built using https://antora.org[Antora]. +This README covers how to build the docs in a software branch as well as how to build the production docs site locally. -Spring Cloud Vault Config provides client-side support for externalized configuration in a distributed system. -With https://www.vaultproject.io[HashiCorp's Vault] you have a central place to manage external secret properties for applications across all environments. -Vault can manage static and dynamic secrets such as username/password for remote applications/resources and provide credentials for external services such as MySQL, PostgreSQL, Apache Cassandra, Couchbase, MongoDB, Consul, AWS and more. +== Building the Site -== Features - -=== Spring Cloud Vault Config Client - -Specifically for Spring applications: - -* Retrieve secrets from Vault and initialize Spring Environment with remote property sources. -* Obtain {docs}#vault.config.backends.kv[Key-Value secrets] secured with SSL. -* Generate credentials for -{docs}#vault.config.backends.mysql[MySQL], -{docs}#vault.config.backends.postgresql[PostgreSQL], -{docs}#vault.config.backends.cassandra[Apache Cassandra], -{docs}#vault.config.backends.mongodb[MongoDB], -{docs}#vault.config.backends.consul[Consul], -{docs}#vault.config.backends.aws[AWS], and {docs}#vault.config.backends.rabbitmq[RabbitMQ]. -* {docs}#vault.config.authentication.token[Token], -{docs}#vault.config.authentication.appid[AppId], -{docs}#vault.config.authentication.approle[AppRole], -{docs}#vault.config.authentication.clientcert[Client Certificate], -{docs}#vault.config.authentication.cubbyhole[Cubbyhole], -{docs}#vault.config.authentication.awsec2[AWS-EC2] authentication, -{docs}#vault.config.authentication.awsiam[AWS-IAM] authentication, and -{docs}#vault.config.authentication.kubernetes[Kubernetes] authentication. - -* Bootstrap application context: a parent context for the main application that can be trained to do anything. - -== Quick Start - -:docs: https://cloud.spring.io/spring-cloud-vault/reference/html/ - -*Prerequisites* - -To get started with Vault and this guide you need a *NIX-like operating systems that provides: - -* `wget`, `openssl` and `unzip` -* at least Java 8 and a properly configured `JAVA_HOME` environment variable - -NOTE: This guide explains Vault setup from a Spring Cloud Vault perspective for integration testing. -You can find a getting started guide directly on the Vault project site: https://learn.hashicorp.com/vault - -*Install Vault* +You can build the entire site by invoking the following on the docs-build branch and then viewing the site at `target/site/index.html` [source,bash] ---- -$ wget https://releases.hashicorp.com/vault/${vault_version}/vault_${vault_version}_${platform}.zip -$ unzip vault_${vault_version}_${platform}.zip +./mvnw antora ---- -NOTE: These steps can be achieved by downloading and running https://github.com/spring-cloud/spring-cloud-vault/blob/master/src/test/bash/install_vault.sh[`install_vault.sh`]. - -*Create SSL certificates for Vault* - -Next, you'r required to generate a set of certificates: - -* Root CA -* Vault Certificate (decrypted key `work/ca/private/localhost.decrypted.key.pem` and certificate `work/ca/certs/localhost.cert.pem`) - -Make sure to import the Root Certificate into a Java-compliant truststore. - -The easiest way to achieve this is by using OpenSSL. - -NOTE: https://github.com/spring-cloud/spring-cloud-vault/blob/master/src/test/bash/[`create_certificates.sh`] creates certificates in `work/ca` and a JKS truststore `work/keystore.jks`. -If you want to run Spring Cloud Vault using this quickstart guide you need to configure the truststore the `spring.cloud.vault.ssl.trust-store` property to `file:work/keystore.jks`. - -[[quickstart.vault.start]] -*Start Vault server* - -Next create a config file along the lines of: - -[source] ----- -backend "inmem" { -} - -listener "tcp" { - address = "0.0.0.0:8200" - tls_cert_file = "work/ca/certs/localhost.cert.pem" - tls_key_file = "work/ca/private/localhost.decrypted.key.pem" -} - -disable_mlock = true ----- - -NOTE: You can find an example config file at https://github.com/spring-clod/spring-cloud-vault/blob/master/src/test/bash/vault.conf[`vault.conf`]. +== Building a Specific Branch [source,bash] ---- -$ vault server -config=vault.conf +./mvnw antora ---- - -Vault is started listening on `0.0.0.0:8200` using the `inmem` storage and `https`. -Vault is sealed and not initialized when starting up. - -NOTE: If you want to run tests, leave Vault uninitialized. -The tests will initialize Vault and create a root token `00000000-0000-0000-0000-000000000000`. - -If you want to use Vault for your application or give it a try then you need to initialize it first. - -[source,bash] ----- -$ export VAULT_ADDR="https://localhost:8200" -$ export VAULT_SKIP_VERIFY=true # Don't do this for production -$ vault operator init ----- - -You should see something like: - -[source,bash] ----- -Key 1: 7149c6a2e16b8833f6eb1e76df03e47f6113a3288b3093faf5033d44f0e70fe701 -Key 2: 901c534c7988c18c20435a85213c683bdcf0efcd82e38e2893779f152978c18c02 -Key 3: 03ff3948575b1165a20c20ee7c3e6edf04f4cdbe0e82dbff5be49c63f98bc03a03 -Key 4: 216ae5cc3ddaf93ceb8e1d15bb9fc3176653f5b738f5f3d1ee00cd7dccbe926e04 -Key 5: b2898fc8130929d569c1677ee69dc5f3be57d7c4b494a6062693ce0b1c4d93d805 -Initial Root Token: 19aefa97-cccc-bbbb-aaaa-225940e63d76 - -Vault initialized with 5 keys and a key threshold of 3. Please -securely distribute the above keys. When the Vault is re-sealed, -restarted, or stopped, you must provide at least 3 of these keys -to unseal it again. - -Vault does not store the master key. Without at least 3 keys, -your Vault will remain permanently sealed. ----- - -Vault will initialize and return a set of unsealing keys and the root token. -Pick 3 keys and unseal Vault. -Store the Vault token in the `VAULT_TOKEN` -environment variable. - -[source,bash] ----- -$ vault operator unseal (Key 1) -$ vault operator unseal (Key 2) -$ vault operator unseal (Key 3) -$ export VAULT_TOKEN=(Root token) -# Required to run Spring Cloud Vault tests after manual initialization -$ vault token create -id="00000000-0000-0000-0000-000000000000" -policy="root" ----- - -Spring Cloud Vault accesses different resources. -By default, the secret backend is enabled which accesses secret config settings via JSON endpoints. - -The HTTP service has resources in the form: - ----- -/secret/{application}/{profile} -/secret/{application} -/secret/{defaultContext}/{profile} -/secret/{defaultContext} ----- - -where the "application" is injected as the `spring.application.name` in the -`SpringApplication` (i.e. what is normally "application" in a regular Spring Boot app), "profile" is an active profile (or comma-separated list of properties). -Properties retrieved from Vault will be used "as-is" without further prefixing of the property names. - -== Client Side Usage - -To use these features in an application, just build it as a Spring Boot application that depends on `spring-cloud-vault-config` (e.g. see the test cases). -Example Maven configuration: - -.pom.xml -==== -[source,xml,indent=0,subs="verbatim,quotes,attributes"] ----- - - org.springframework.boot - spring-boot-starter-parent - 2.4.0.RELEASE - - - - - - org.springframework.cloud - spring-cloud-starter-vault-config - {project-version} - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - ----- -==== - -Then you can create a standard Spring Boot application, like this simple HTTP server: - -==== -[source,java] ----- -@SpringBootApplication -@RestController -public class Application { - - @RequestMapping("/") - public String home() { - return "Hello World!"; - } - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} ----- -==== - -When it runs it will pick up the external configuration from the default local Vault server on port `8200` if it is running. -To modify the startup behavior you can change the location of the Vault server using `application.properties`, for example - -.application.yml -==== -[source,yaml] ----- -spring.cloud.vault: - host: localhost - port: 8200 - scheme: https - uri: https://localhost:8200 - connection-timeout: 5000 - read-timeout: 15000 - config: -spring.config.import: vault:// ----- -==== - -* `host` sets the hostname of the Vault host. -The host name will be used for SSL certificate validation -* `port` sets the Vault port -* `scheme` setting the scheme to `http` will use plain HTTP. -Supported schemes are `http` and `https`. -* `uri` configure the Vault endpoint with an URI. Takes precedence over host/port/scheme configuration -* `connection-timeout` sets the connection timeout in milliseconds -* `read-timeout` sets the read timeout in milliseconds -* `spring.config.import` mounts Vault as `PropertySource` using all enabled secret backends (key-value enabled by default) - -Enabling further integrations requires additional dependencies and configuration. -Depending on how you have set up Vault you might need additional configuration like -{docs}#vault.config.ssl[SSL] and -{docs}#vault.config.authentication[authentication]. - -If the application imports the `spring-boot-starter-actuator` project, the status of the vault server will be available via the `/health` endpoint. - -The vault health indicator can be enabled or disabled through the property `management.health.vault.enabled` (default to `true`). - -NOTE: With Spring Cloud Vault 3.0 and Spring Boot 2.4, the bootstrap context initialization (`bootstrap.yml`, `bootstrap.properties`) of property sources was deprecated. -Instead, Spring Cloud Vault favors Spring Boot's Config Data API which allows importing configuration from Vault. With Spring Boot Config Data approach, you need to set the `spring.config.import` property in order to bind to Vault. You can read more about it in the <>. -You can enable the bootstrap context either by setting the configuration property `spring.cloud.bootstrap.enabled=true` or by including the dependency `org.springframework.cloud:spring-cloud-starter-bootstrap`. - -=== Authentication - -Vault requires an https://www.vaultproject.io/docs/concepts/auth.html[authentication mechanism] to https://www.vaultproject.io/docs/concepts/tokens.html[authorize client requests]. - -Spring Cloud Vault supports multiple {docs}#vault.config.authentication[authentication mechanisms] to authenticate applications with Vault. - -For a quickstart, use the root token printed by the <>. - -.application.yml -==== -[source,yaml] ----- -spring.cloud.vault: - token: 19aefa97-cccc-bbbb-aaaa-225940e63d76 -spring.config.import: vault:// ----- -==== - -WARNING: Consider carefully your security requirements. -Static token authentication is fine if you want quickly get started with Vault, but a static token is not protected any further. -Any disclosure to unintended parties allows Vault use with the associated token roles. - - - - -== Building - -=== Build requirements for Vault - -Spring Cloud Vault Config requires SSL certificates and a running Vault instance listening on `localhost:8200`. -Certificates and the Vault setup are scripted, the scripts are located in `src/test/bash`. - -The following scripts need to be run prior to building the project for the tests to pass. - -[source,bash] ----- -$ ./src/test/bash/install_vault.sh -$ ./src/test/bash/create_certificates.sh -$ ./src/test/bash/local_run_vault.sh ----- - -Leave Vault uninitialized, the tests will initialize and unseal Vault. -They will also create a root token `00000000-0000-0000-0000-000000000000`. - -Changes to the documentation should be made to the adocs found under `docs/src/main/asciidoc/` - -`README.adoc` can be re-generated via the following - -[source,bash] ----- -$ ./docs/src/main/ruby/generate_readme.sh > README.adoc ----- - -This script requires ruby and the asciidoctor gem installed (`gem install asciidoctor`) - -:jdkversion: 17 - -=== Basic Compile and Test - -To build the source you will need to install JDK {jdkversion}. - -Spring Cloud uses Maven for most build-related activities, and you -should be able to get off the ground quite quickly by cloning the -project you are interested in and typing - ----- -$ ./mvnw install ----- - -NOTE: You can also install Maven (>=3.3.3) yourself and run the `mvn` command -in place of `./mvnw` in the examples below. If you do that you also -might need to add `-P spring` if your local Maven settings do not -contain repository declarations for spring pre-release artifacts. - -NOTE: Be aware that you might need to increase the amount of memory -available to Maven by setting a `MAVEN_OPTS` environment variable with -a value like `-Xmx512m -XX:MaxPermSize=128m`. We try to cover this in -the `.mvn` configuration, so if you find you have to do it to make a -build succeed, please raise a ticket to get the settings added to -source control. - -The projects that require middleware (i.e. Redis) for testing generally -require that a local instance of [Docker](https://www.docker.com/get-started) is installed and running. - - -=== Documentation - -The spring-cloud-build module has a "docs" profile, and if you switch -that on it will try to build asciidoc sources from -`src/main/asciidoc`. As part of that process it will look for a -`README.adoc` and process it by loading all the includes, but not -parsing or rendering it, just copying it to `${main.basedir}` -(defaults to `${basedir}`, i.e. the root of the project). If there are -any changes in the README it will then show up after a Maven build as -a modified file in the correct place. Just commit it and push the change. - -=== Working with the code -If you don't have an IDE preference we would recommend that you use -https://www.springsource.com/developer/sts[Spring Tools Suite] or -https://eclipse.org[Eclipse] when working with the code. We use the -https://eclipse.org/m2e/[m2eclipse] eclipse plugin for maven support. Other IDEs and tools -should also work without issue as long as they use Maven 3.3.3 or better. - -==== Activate the Spring Maven profile -Spring Cloud projects require the 'spring' Maven profile to be activated to resolve -the spring milestone and snapshot repositories. Use your preferred IDE to set this -profile to be active, or you may experience build errors. - -==== Importing into eclipse with m2eclipse -We recommend the https://eclipse.org/m2e/[m2eclipse] eclipse plugin when working with -eclipse. If you don't already have m2eclipse installed it is available from the "eclipse -marketplace". - -NOTE: Older versions of m2e do not support Maven 3.3, so once the -projects are imported into Eclipse you will also need to tell -m2eclipse to use the right profile for the projects. If you -see many different errors related to the POMs in the projects, check -that you have an up to date installation. If you can't upgrade m2e, -add the "spring" profile to your `settings.xml`. Alternatively you can -copy the repository settings from the "spring" profile of the parent -pom into your `settings.xml`. - -==== Importing into eclipse without m2eclipse -If you prefer not to use m2eclipse you can generate eclipse project metadata using the -following command: - -[indent=0] ----- - $ ./mvnw eclipse:eclipse ----- - -The generated eclipse projects can be imported by selecting `import existing projects` -from the `file` menu. - - -== Contributing - -:spring-cloud-build-branch: master - -Spring Cloud is released under the non-restrictive Apache 2.0 license, -and follows a very standard Github development process, using Github -tracker for issues and merging pull requests into master. If you want -to contribute even something trivial please do not hesitate, but -follow the guidelines below. - -=== Sign the Contributor License Agreement -Before we accept a non-trivial patch or pull request we will need you to sign the -https://cla.pivotal.io/sign/spring[Contributor License Agreement]. -Signing the contributor's agreement does not grant anyone commit rights to the main -repository, but it does mean that we can accept your contributions, and you will get an -author credit if we do. Active contributors might be asked to join the core team, and -given the ability to merge pull requests. - -=== Code of Conduct -This project adheres to the Contributor Covenant https://github.com/spring-cloud/spring-cloud-build/blob/master/docs/src/main/asciidoc/code-of-conduct.adoc[code of -conduct]. By participating, you are expected to uphold this code. Please report -unacceptable behavior to spring-code-of-conduct@pivotal.io. - -=== Code Conventions and Housekeeping -None of these is essential for a pull request, but they will all help. They can also be -added after the original pull request but before a merge. - -* Use the Spring Framework code format conventions. If you use Eclipse - you can import formatter settings using the - `eclipse-code-formatter.xml` file from the - https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-dependencies-parent/eclipse-code-formatter.xml[Spring - Cloud Build] project. If using IntelliJ, you can use the - https://plugins.jetbrains.com/plugin/6546[Eclipse Code Formatter - Plugin] to import the same file. -* Make sure all new `.java` files to have a simple Javadoc class comment with at least an - `@author` tag identifying you, and preferably at least a paragraph on what the class is - for. -* Add the ASF license header comment to all new `.java` files (copy from existing files - in the project) -* Add yourself as an `@author` to the .java files that you modify substantially (more - than cosmetic changes). -* Add some Javadocs and, if you change the namespace, some XSD doc elements. -* A few unit tests would help a lot as well -- someone has to do it. -* If no-one else is using your branch, please rebase it against the current master (or - other target branch in the main project). -* When writing a commit message please follow https://tbaggery.com/2008/04/19/a-note-about-git-commit-messages.html[these conventions], - if you are fixing an existing issue please add `Fixes gh-XXXX` at the end of the commit - message (where XXXX is the issue number). - -=== Checkstyle - -Spring Cloud Build comes with a set of checkstyle rules. You can find them in the `spring-cloud-build-tools` module. The most notable files under the module are: - -.spring-cloud-build-tools/ ----- -└── src -    ├── checkstyle -    │   └── checkstyle-suppressions.xml <3> -    └── main -    └── resources -    ├── checkstyle-header.txt <2> -    └── checkstyle.xml <1> ----- -<1> Default Checkstyle rules -<2> File header setup -<3> Default suppression rules - -==== Checkstyle configuration - -Checkstyle rules are *disabled by default*. To add checkstyle to your project just define the following properties and plugins. - -.pom.xml ----- - -true <1> - true - <2> - true - <3> - - - - - <4> - io.spring.javaformat - spring-javaformat-maven-plugin - - <5> - org.apache.maven.plugins - maven-checkstyle-plugin - - - - - - <5> - org.apache.maven.plugins - maven-checkstyle-plugin - - - - ----- -<1> Fails the build upon Checkstyle errors -<2> Fails the build upon Checkstyle violations -<3> Checkstyle analyzes also the test sources -<4> Add the Spring Java Format plugin that will reformat your code to pass most of the Checkstyle formatting rules -<5> Add checkstyle plugin to your build and reporting phases - -If you need to suppress some rules (e.g. line length needs to be longer), then it's enough for you to define a file under `${project.root}/src/checkstyle/checkstyle-suppressions.xml` with your suppressions. Example: - -.projectRoot/src/checkstyle/checkstyle-suppresions.xml ----- - - - - - - ----- - -It's advisable to copy the `${spring-cloud-build.rootFolder}/.editorconfig` and `${spring-cloud-build.rootFolder}/.springformat` to your project. That way, some default formatting rules will be applied. You can do so by running this script: - -```bash -$ curl https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/.editorconfig -o .editorconfig -$ touch .springformat -``` - -=== IDE setup - -==== Intellij IDEA - -In order to setup Intellij you should import our coding conventions, inspection profiles and set up the checkstyle plugin. -The following files can be found in the https://github.com/spring-cloud/spring-cloud-build/tree/master/spring-cloud-build-tools[Spring Cloud Build] project. - -.spring-cloud-build-tools/ ----- -└── src -    ├── checkstyle -    │   └── checkstyle-suppressions.xml <3> -    └── main -    └── resources -    ├── checkstyle-header.txt <2> -    ├── checkstyle.xml <1> -    └── intellij -       ├── Intellij_Project_Defaults.xml <4> -       └── Intellij_Spring_Boot_Java_Conventions.xml <5> ----- -<1> Default Checkstyle rules -<2> File header setup -<3> Default suppression rules -<4> Project defaults for Intellij that apply most of Checkstyle rules -<5> Project style conventions for Intellij that apply most of Checkstyle rules - -.Code style - -image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-code-style.png[Code style] - -Go to `File` -> `Settings` -> `Editor` -> `Code style`. There click on the icon next to the `Scheme` section. There, click on the `Import Scheme` value and pick the `Intellij IDEA code style XML` option. Import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Spring_Boot_Java_Conventions.xml` file. - -.Inspection profiles - -image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-inspections.png[Code style] - -Go to `File` -> `Settings` -> `Editor` -> `Inspections`. There click on the icon next to the `Profile` section. There, click on the `Import Profile` and import the `spring-cloud-build-tools/src/main/resources/intellij/Intellij_Project_Defaults.xml` file. - -.Checkstyle - -To have Intellij work with Checkstyle, you have to install the `Checkstyle` plugin. It's advisable to also install the `Assertions2Assertj` to automatically convert the JUnit assertions - -image::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/{spring-cloud-build-branch}/docs/src/main/asciidoc/images/intellij-checkstyle.png[Checkstyle] - -Go to `File` -> `Settings` -> `Other settings` -> `Checkstyle`. There click on the `+` icon in the `Configuration file` section. There, you'll have to define where the checkstyle rules should be picked from. In the image above, we've picked the rules from the cloned Spring Cloud Build repository. However, you can point to the Spring Cloud Build's GitHub repository (e.g. for the `checkstyle.xml` : `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle.xml`). We need to provide the following variables: - -- `checkstyle.header.file` - please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/main/resources/checkstyle-header.txt` URL. -- `checkstyle.suppressions.file` - default suppressions. Please point it to the Spring Cloud Build's, `spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` file either in your cloned repo or via the `https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/spring-cloud-build-tools/src/checkstyle/checkstyle-suppressions.xml` URL. -- `checkstyle.additional.suppressions.file` - this variable corresponds to suppressions in your local project. E.g. you're working on `spring-cloud-contract`. Then point to the `project-root/src/checkstyle/checkstyle-suppressions.xml` folder. Example for `spring-cloud-contract` would be: `/home/username/spring-cloud-contract/src/checkstyle/checkstyle-suppressions.xml`. - -IMPORTANT: Remember to set the `Scan Scope` to `All sources` since we apply checkstyle rules for production and test sources. - -=== Duplicate Finder - -Spring Cloud Build brings along the `basepom:duplicate-finder-maven-plugin`, that enables flagging duplicate and conflicting classes and resources on the java classpath. - -==== Duplicate Finder configuration - -Duplicate finder is *enabled by default* and will run in the `verify` phase of your Maven build, but it will only take effect in your project if you add the `duplicate-finder-maven-plugin` to the `build` section of the projecst's `pom.xml`. - -.pom.xml -[source,xml] ----- - - - - org.basepom.maven - duplicate-finder-maven-plugin - - - ----- - -For other properties, we have set defaults as listed in the https://github.com/basepom/duplicate-finder-maven-plugin/wiki[plugin documentation]. - -You can easily override them but setting the value of the selected property prefixed with `duplicate-finder-maven-plugin`. For example, set `duplicate-finder-maven-plugin.skip` to `true` in order to skip duplicates check in your build. - -If you need to add `ignoredClassPatterns` or `ignoredResourcePatterns` to your setup, make sure to add them in the plugin configuration section of your project: - -[source,xml] ----- - - - - org.basepom.maven - duplicate-finder-maven-plugin - - - org.joda.time.base.BaseDateTime - .*module-info - - - changelog.txt - - - - - - - ----- - diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index 04685956..00000000 --- a/SECURITY.md +++ /dev/null @@ -1,5 +0,0 @@ -# Security Policy - -## Reporting a Vulnerability - -To report security vulnerabilities, please go to https://pivotal.io/security. diff --git a/docs/antora-playbook.yml b/antora-playbook.yml similarity index 61% rename from docs/antora-playbook.yml rename to antora-playbook.yml index 9a70e676..93d8a572 100644 --- a/docs/antora-playbook.yml +++ b/antora-playbook.yml @@ -6,38 +6,39 @@ antora: - '@antora/collector-extension' - '@antora/atlas-extension' - require: '@springio/antora-extensions/root-component-extension' - root_component_name: 'PROJECT_WITHOUT_SPRING' - # FIXME: Run antora once using this extension to migrate to the Asciidoc Tabs syntax - # and then remove this extension - - require: '@springio/antora-extensions/tabs-migration-extension' - unwrap_example_block: always - save_result: true + root_component_name: 'cloud-vault' site: - title: PROJECT_FULL_NAME - url: https://docs.spring.io/PROJECT_NAME/reference/ + title: Spring Cloud Vault + url: https://docs.spring.io/spring-cloud-vault/reference + robots: allow +git: + ensure_git_suffix: false content: sources: - - url: ./.. - branches: HEAD + - url: https://github.com/spring-cloud/spring-cloud-vault + # Refname matching: + # https://docs.antora.org/antora/latest/playbook/content-refname-matching/ + branches: [ main ] + tags: [ '({4..9}).+({1..9}).+({0..9})?(-{RC,M}+({0..9}))', '!4.1.0-M1' ] start_path: docs - worktrees: true asciidoc: attributes: page-stackoverflow-url: https://stackoverflow.com/tags/spring-cloud page-pagination: '' hide-uri-scheme: '@' tabs-sync-option: '@' - chomp: 'all' extensions: - '@asciidoctor/tabs' - '@springio/asciidoctor-extensions' - sourcemap: true urls: + latest_version_segment_strategy: redirect:to latest_version_segment: '' + redirect_facility: httpd +ui: + bundle: + url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.5/ui-bundle.zip + snapshot: true runtime: log: failure_level: warn format: pretty -ui: - bundle: - url: https://github.com/spring-io/antora-ui-spring/releases/download/v0.3.5/ui-bundle.zip diff --git a/config/build.sh b/config/build.sh deleted file mode 100755 index aeb541a7..00000000 --- a/config/build.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -./src/test/bash/install_vault.sh -./src/test/bash/create_certificates.sh -./src/test/bash/local_run_vault.sh & -./mvnw clean install -Pdocs && pkill -f "vault server" diff --git a/config/releaser.yml b/config/releaser.yml deleted file mode 100644 index 7a1b4c30..00000000 --- a/config/releaser.yml +++ /dev/null @@ -1,3 +0,0 @@ -releaser: - maven: - buildCommand: ./config/build.sh diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 39f5469c..00000000 --- a/docker-compose.yml +++ /dev/null @@ -1,8 +0,0 @@ -# Work in Progress -vault: - image: cgswong/vault - volumes: - - ./src/test/resources:/config - ports: - - "8200:8200" - command: server -config /config/vault.conf diff --git a/docs/.flattened-pom.xml b/docs/.flattened-pom.xml new file mode 100644 index 00000000..c14db461 --- /dev/null +++ b/docs/.flattened-pom.xml @@ -0,0 +1,155 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-vault-parent + 4.1.0-SNAPSHOT + .. + + org.springframework.cloud + spring-cloud-vault-docs + 4.1.0-SNAPSHOT + Spring Cloud Vault Docs + Spring Cloud Docs + https://spring.io/spring-cloud/spring-cloud-vault-parent/spring-cloud-vault-docs + + Pivotal Software, Inc. + https://www.spring.io + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + Copyright 2014-2021 the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. + + See the License for the specific language governing permissions and + limitations under the License. + + + + + dsyer + Dave Syer + dsyer at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + sgibb + Spencer Gibb + sgibb at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + mgrzejszczak + Marcin Grzejszczak + mgrzejszczak at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + rbaxter + Ryan Baxter + rbaxter at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + omaciaszeksharma + Olga Maciaszek-Sharma + omaciaszeksharma at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + + scm:git:git://github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-docs + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-docs + https://github.com/spring-cloud/spring-cloud-vault/spring-cloud-vault-docs + + + + org.springframework.cloud + spring-cloud-starter-vault-config + 4.1.0-SNAPSHOT + compile + + + org.springframework.cloud + spring-cloud-vault-config-aws + 4.1.0-SNAPSHOT + compile + + + org.springframework.cloud + spring-cloud-vault-config-consul + 4.1.0-SNAPSHOT + compile + + + org.springframework.cloud + spring-cloud-vault-config-databases + 4.1.0-SNAPSHOT + compile + + + org.springframework.cloud + spring-cloud-vault-config-rabbitmq + 4.1.0-SNAPSHOT + compile + + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + + org.hibernate.validator + hibernate-validator + 8.0.0.Final + provided + + + org.springframework.boot + spring-boot-autoconfigure + 3.2.0-SNAPSHOT + provided + + + org.springframework.boot + spring-boot-starter + 3.2.0-SNAPSHOT + provided + + + diff --git a/docs/.github/workflows/deploy-docs.yml b/docs/.github/workflows/deploy-docs.yml deleted file mode 100644 index be4b92df..00000000 --- a/docs/.github/workflows/deploy-docs.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Deploy Docs -on: - push: - branches-ignore: [ gh-pages ] - tags: '**' - repository_dispatch: - types: request-build-reference # legacy - #schedule: - #- cron: '0 10 * * *' # Once per day at 10am UTC - workflow_dispatch: -permissions: - actions: write -jobs: - build: - runs-on: ubuntu-latest - # if: github.repository_owner == 'spring-cloud' - steps: - - name: Checkout - uses: actions/checkout@v3 - with: - ref: docs-build - fetch-depth: 1 - - name: Dispatch (partial build) - if: github.ref_type == 'branch' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) -f build-refname=${{ github.ref_name }} - - name: Dispatch (full build) - if: github.ref_type == 'tag' - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: gh workflow run deploy-docs.yml -r $(git rev-parse --abbrev-ref HEAD) diff --git a/docs/antora.yml b/docs/antora.yml deleted file mode 100644 index 15b346da..00000000 --- a/docs/antora.yml +++ /dev/null @@ -1,12 +0,0 @@ -name: PROJECT_WITHOUT_SPRING -version: true -title: PROJECT_NAME -nav: - - modules/ROOT/nav.adoc -ext: - collector: - run: - command: ./mvnw --no-transfer-progress -B process-resources -Pdocs -pl docs -Dantora-maven-plugin.phase=none -Dgenerate-docs.phase=none -Dgenerate-readme.phase=none -Dgenerate-cloud-resources.phase=none -Dmaven-dependency-plugin-for-docs.phase=none -Dmaven-dependency-plugin-for-docs-classes.phase=none -DskipTests - local: true - scan: - dir: ./target/classes/antora-resources/ diff --git a/docs/modules/ROOT/nav.adoc b/docs/modules/ROOT/nav.adoc deleted file mode 100644 index 4c1d92a4..00000000 --- a/docs/modules/ROOT/nav.adoc +++ /dev/null @@ -1,13 +0,0 @@ -* xref:index.adoc[] -* xref:intro.adoc[] -* xref:_attributes.adoc[] -* xref:new-features.adoc[] -* xref:quickstart.adoc[] -* xref:config-data.adoc[] -* xref:authentication.adoc[] -* xref:secret-backends.adoc[] -* xref:other-topics.adoc[] -* xref:appendix.adoc[] -* xref:_configprops.adoc[] -* xref:README.adoc[] -* xref:spring-cloud-vault.adoc[] diff --git a/docs/modules/ROOT/pages/README.adoc b/docs/modules/ROOT/pages/README.adoc deleted file mode 100644 index bff0b295..00000000 --- a/docs/modules/ROOT/pages/README.adoc +++ /dev/null @@ -1,73 +0,0 @@ -:docs: https://cloud.spring.io/spring-cloud-vault/spring-cloud-vault.html - - -[[features]] -= Features - -[[spring-cloud-vault-config-client]] -== Spring Cloud Vault Config Client - -Specifically for Spring applications: - -* Retrieve secrets from Vault and initialize Spring Environment with remote property sources. -* Obtain {docs}#vault.config.backends.kv[Key-Value secrets] secured with SSL. -* Generate credentials for -{docs}#vault.config.backends.mysql[MySQL], -{docs}#vault.config.backends.postgresql[PostgreSQL], -{docs}#vault.config.backends.cassandra[Apache Cassandra], -{docs}#vault.config.backends.mongodb[MongoDB], -{docs}#vault.config.backends.consul[Consul], -{docs}#vault.config.backends.aws[AWS], and {docs}#vault.config.backends.rabbitmq[RabbitMQ]. -* {docs}#vault.config.authentication.token[Token], -{docs}#vault.config.authentication.appid[AppId], -{docs}#vault.config.authentication.approle[AppRole], -{docs}#vault.config.authentication.clientcert[Client Certificate], -{docs}#vault.config.authentication.cubbyhole[Cubbyhole], -{docs}#vault.config.authentication.awsec2[AWS-EC2] authentication, -{docs}#vault.config.authentication.awsiam[AWS-IAM] authentication, and -{docs}#vault.config.authentication.kubernetes[Kubernetes] authentication. - -* Bootstrap application context: a parent context for the main application that can be trained to do anything. - -[[quick-start]] -= Quick Start - - -[[building]] -= Building - -[[build-requirements-for-vault]] -== Build requirements for Vault - -Spring Cloud Vault Config requires SSL certificates and a running Vault instance listening on `localhost:8200`. -Certificates and the Vault setup are scripted, the scripts are located in `src/test/bash`. - -The following scripts need to be run prior to building the project for the tests to pass. - -[source,bash] ----- -$ ./src/test/bash/install_vault.sh -$ ./src/test/bash/create_certificates.sh -$ ./src/test/bash/local_run_vault.sh ----- - -Leave Vault uninitialized, the tests will initialize and unseal Vault. -They will also create a root token `00000000-0000-0000-0000-000000000000`. - -Changes to the documentation should be made to the adocs found under `docs/src/main/asciidoc/` - -`README.adoc` can be re-generated via the following - -[source,bash] ----- -$ ./docs/src/main/ruby/generate_readme.sh > README.adoc ----- - -This script requires ruby and the asciidoctor gem installed (`gem install asciidoctor`) - -include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/building.adoc[] - -[[contributing]] -= Contributing - -include::https://raw.githubusercontent.com/spring-cloud/spring-cloud-build/master/docs/src/main/asciidoc/contributing.adoc[] diff --git a/docs/modules/ROOT/pages/_attributes.adoc b/docs/modules/ROOT/pages/_attributes.adoc deleted file mode 100644 index 731e8d7c..00000000 --- a/docs/modules/ROOT/pages/_attributes.adoc +++ /dev/null @@ -1,13 +0,0 @@ -:doctype: book -:idprefix: -:idseparator: - -:tabsize: 4 -:numbered: -:sectanchors: -:sectnums: -:icons: font -:hide-uri-scheme: -:docinfo: shared,private - -:sc-ext: java -:project-full-name: Spring Cloud Vault diff --git a/docs/modules/ROOT/pages/_configprops.adoc b/docs/modules/ROOT/pages/_configprops.adoc deleted file mode 100644 index 0a77b628..00000000 --- a/docs/modules/ROOT/pages/_configprops.adoc +++ /dev/null @@ -1,140 +0,0 @@ -|=== -|Name | Default | Description - -|spring.cloud.vault.app-id.app-id-path | `+++app-id+++` | Mount path of the AppId authentication backend. -|spring.cloud.vault.app-id.network-interface | | Network interface hint for the "MAC_ADDRESS" UserId mechanism. -|spring.cloud.vault.app-id.user-id | `+++MAC_ADDRESS+++` | UserId mechanism. Can be either "MAC_ADDRESS", "IP_ADDRESS", a string or a class name. -|spring.cloud.vault.app-role.app-role-path | `+++approle+++` | Mount path of the AppRole authentication backend. -|spring.cloud.vault.app-role.role | | Name of the role, optional, used for pull-mode. -|spring.cloud.vault.app-role.role-id | | The RoleId. -|spring.cloud.vault.app-role.secret-id | | The SecretId. -|spring.cloud.vault.application-name | `+++application+++` | Application name for AppId authentication. -|spring.cloud.vault.authentication | | -|spring.cloud.vault.aws-ec2.aws-ec2-path | `+++aws-ec2+++` | Mount path of the AWS-EC2 authentication backend. -|spring.cloud.vault.aws-ec2.identity-document | `+++http://169.254.169.254/latest/dynamic/instance-identity/pkcs7+++` | URL of the AWS-EC2 PKCS7 identity document. -|spring.cloud.vault.aws-ec2.nonce | | Nonce used for AWS-EC2 authentication. An empty nonce defaults to nonce generation. -|spring.cloud.vault.aws-ec2.role | | Name of the role, optional. -|spring.cloud.vault.aws-iam.aws-path | `+++aws+++` | Mount path of the AWS authentication backend. -|spring.cloud.vault.aws-iam.endpoint-uri | | STS server URI. @since 2.2 -|spring.cloud.vault.aws-iam.region | | Name of the region, optional. Inferred by AWS defaults if not set. @since 4.0.1 -|spring.cloud.vault.aws-iam.role | | Name of the role, optional. Defaults to the friendly IAM name if not set. -|spring.cloud.vault.aws-iam.server-name | | Name of the server used to set {@code X-Vault-AWS-IAM-Server-ID} header in the headers of login requests. -|spring.cloud.vault.aws.access-key-property | `+++cloud.aws.credentials.accessKey+++` | Target property for the obtained access key. -|spring.cloud.vault.aws.backend | `+++aws+++` | aws backend path. -|spring.cloud.vault.aws.credential-type | | aws credential type -|spring.cloud.vault.aws.enabled | `+++false+++` | Enable aws backend usage. -|spring.cloud.vault.aws.role | | Role name for credentials. -|spring.cloud.vault.aws.role-arn | | Role arn for assumed_role in case we have multiple roles associated with the vault role. @since 3.0.2 -|spring.cloud.vault.aws.secret-key-property | `+++cloud.aws.credentials.secretKey+++` | Target property for the obtained secret key. -|spring.cloud.vault.aws.session-token-key-property | `+++cloud.aws.credentials.sessionToken+++` | Target property for the obtained secret key. -|spring.cloud.vault.aws.ttl | `+++0+++` | TTL for sts tokens. Defaults to whatever the vault Role may have for Max. Also limited to what AWS supports to be the max for STS. @since 3.0.2 -|spring.cloud.vault.azure-msi.azure-path | `+++azure+++` | Mount path of the Azure MSI authentication backend. -|spring.cloud.vault.azure-msi.identity-token-service | | Identity token service URI. @since 3.0 -|spring.cloud.vault.azure-msi.metadata-service | | Instance metadata service URI. @since 3.0 -|spring.cloud.vault.azure-msi.role | | Name of the role. -|spring.cloud.vault.cassandra.backend | `+++cassandra+++` | Cassandra backend path. -|spring.cloud.vault.cassandra.enabled | `+++false+++` | Enable cassandra backend usage. -|spring.cloud.vault.cassandra.password-property | `+++spring.data.cassandra.password+++` | Target property for the obtained password. -|spring.cloud.vault.cassandra.role | | Role name for credentials. -|spring.cloud.vault.cassandra.static-role | `+++false+++` | Enable static role usage. @since 2.2 -|spring.cloud.vault.cassandra.username-property | `+++spring.data.cassandra.username+++` | Target property for the obtained username. -|spring.cloud.vault.config.lifecycle.enabled | `+++true+++` | Enable lifecycle management. -|spring.cloud.vault.config.lifecycle.expiry-threshold | | The expiry threshold. {@link Lease} is renewed the given {@link Duration} before it expires. @since 2.2 -|spring.cloud.vault.config.lifecycle.lease-endpoints | | Set the {@link LeaseEndpoints} to delegate renewal/revocation calls to. {@link LeaseEndpoints} encapsulates differences between Vault versions that affect the location of renewal/revocation endpoints. Can be {@link LeaseEndpoints#SysLeases} for version 0.8 or above of Vault or {@link LeaseEndpoints#Legacy} for older versions (the default). @since 2.2 -|spring.cloud.vault.config.lifecycle.min-renewal | | The time period that is at least required before renewing a lease. @since 2.2 -|spring.cloud.vault.config.order | `+++0+++` | Used to set a {@link org.springframework.core.env.PropertySource} priority. This is useful to use Vault as an override on other property sources. @see org.springframework.core.PriorityOrdered -|spring.cloud.vault.connection-timeout | `+++5000+++` | Connection timeout. -|spring.cloud.vault.consul.backend | `+++consul+++` | Consul backend path. -|spring.cloud.vault.consul.enabled | `+++false+++` | Enable consul backend usage. -|spring.cloud.vault.consul.role | | Role name for credentials. -|spring.cloud.vault.consul.token-property | `+++spring.cloud.consul.token+++` | Target property for the obtained token. -|spring.cloud.vault.couchbase.backend | `+++database+++` | Couchbase backend path. -|spring.cloud.vault.couchbase.enabled | `+++false+++` | Enable couchbase backend usage. -|spring.cloud.vault.couchbase.password-property | `+++spring.couchbase.password+++` | Target property for the obtained password. -|spring.cloud.vault.couchbase.role | | Role name for credentials. -|spring.cloud.vault.couchbase.static-role | `+++false+++` | Enable static role usage. -|spring.cloud.vault.couchbase.username-property | `+++spring.couchbase.username+++` | Target property for the obtained username. -|spring.cloud.vault.database.backend | `+++database+++` | Database backend path. -|spring.cloud.vault.database.enabled | `+++false+++` | Enable database backend usage. -|spring.cloud.vault.database.password-property | `+++spring.datasource.password+++` | Target property for the obtained password. -|spring.cloud.vault.database.role | | Role name for credentials. -|spring.cloud.vault.database.static-role | `+++false+++` | Enable static role usage. -|spring.cloud.vault.database.username-property | `+++spring.datasource.username+++` | Target property for the obtained username. -|spring.cloud.vault.databases | | -|spring.cloud.vault.discovery.enabled | `+++false+++` | Flag to indicate that Vault server discovery is enabled (vault server URL will be looked up via discovery). -|spring.cloud.vault.discovery.service-id | `+++vault+++` | Service id to locate Vault. -|spring.cloud.vault.elasticsearch.backend | `+++database+++` | Database backend path. -|spring.cloud.vault.elasticsearch.enabled | `+++false+++` | Enable elasticsearch backend usage. -|spring.cloud.vault.elasticsearch.password-property | `+++spring.elasticsearch.rest.password+++` | Target property for the obtained password. -|spring.cloud.vault.elasticsearch.role | | Role name for credentials. -|spring.cloud.vault.elasticsearch.static-role | `+++false+++` | Enable static role usage. -|spring.cloud.vault.elasticsearch.username-property | `+++spring.elasticsearch.rest.username+++` | Target property for the obtained username. -|spring.cloud.vault.enabled | `+++true+++` | Enable Vault config server. -|spring.cloud.vault.fail-fast | `+++false+++` | Fail fast if data cannot be obtained from Vault. -|spring.cloud.vault.gcp-gce.gcp-path | `+++gcp+++` | Mount path of the Kubernetes authentication backend. -|spring.cloud.vault.gcp-gce.role | | Name of the role against which the login is being attempted. -|spring.cloud.vault.gcp-gce.service-account | | Optional service account id. Using the default id if left unconfigured. -|spring.cloud.vault.gcp-iam.credentials.encoded-key | | The base64 encoded contents of an OAuth2 account private key in JSON format. -|spring.cloud.vault.gcp-iam.credentials.location | | Location of the OAuth2 credentials private key.

Since this is a Resource, the private key can be in a multitude of locations, such as a local file system, classpath, URL, etc. -|spring.cloud.vault.gcp-iam.gcp-path | `+++gcp+++` | Mount path of the Kubernetes authentication backend. -|spring.cloud.vault.gcp-iam.jwt-validity | `+++15m+++` | Validity of the JWT token. -|spring.cloud.vault.gcp-iam.project-id | | Overrides the GCP project Id. -|spring.cloud.vault.gcp-iam.role | | Name of the role against which the login is being attempted. -|spring.cloud.vault.gcp-iam.service-account-id | | Overrides the GCP service account Id. -|spring.cloud.vault.host | `+++localhost+++` | Vault server host. -|spring.cloud.vault.kubernetes.kubernetes-path | `+++kubernetes+++` | Mount path of the Kubernetes authentication backend. -|spring.cloud.vault.kubernetes.role | | Name of the role against which the login is being attempted. -|spring.cloud.vault.kubernetes.service-account-token-file | `+++/var/run/secrets/kubernetes.io/serviceaccount/token+++` | Path to the service account token file. -|spring.cloud.vault.kv.application-name | `+++application+++` | Application name to be used for the context. -|spring.cloud.vault.kv.backend | `+++secret+++` | Name of the default backend. -|spring.cloud.vault.kv.backend-version | `+++2+++` | Key-Value backend version. Currently supported versions are:

-|spring.cloud.vault.kv.default-context | `+++application+++` | Name of the default context. -|spring.cloud.vault.kv.enabled | `+++true+++` | Enable the key-value backend. -|spring.cloud.vault.kv.profile-separator | `+++/+++` | Profile-separator to combine application name and profile. -|spring.cloud.vault.kv.profiles | | List of active profiles. @since 3.0 -|spring.cloud.vault.mongodb.backend | `+++mongodb+++` | MongoDB backend path. -|spring.cloud.vault.mongodb.enabled | `+++false+++` | Enable mongodb backend usage. -|spring.cloud.vault.mongodb.password-property | `+++spring.data.mongodb.password+++` | Target property for the obtained password. -|spring.cloud.vault.mongodb.role | | Role name for credentials. -|spring.cloud.vault.mongodb.static-role | `+++false+++` | Enable static role usage. @since 2.2 -|spring.cloud.vault.mongodb.username-property | `+++spring.data.mongodb.username+++` | Target property for the obtained username. -|spring.cloud.vault.mysql.backend | `+++mysql+++` | mysql backend path. -|spring.cloud.vault.mysql.enabled | `+++false+++` | Enable mysql backend usage. -|spring.cloud.vault.mysql.password-property | `+++spring.datasource.password+++` | Target property for the obtained username. -|spring.cloud.vault.mysql.role | | Role name for credentials. -|spring.cloud.vault.mysql.username-property | `+++spring.datasource.username+++` | Target property for the obtained username. -|spring.cloud.vault.namespace | | Vault namespace (requires Vault Enterprise). -|spring.cloud.vault.pcf.instance-certificate | | Path to the instance certificate (PEM). Defaults to {@code CF_INSTANCE_CERT} env variable. -|spring.cloud.vault.pcf.instance-key | | Path to the instance key (PEM). Defaults to {@code CF_INSTANCE_KEY} env variable. -|spring.cloud.vault.pcf.pcf-path | `+++pcf+++` | Mount path of the Kubernetes authentication backend. -|spring.cloud.vault.pcf.role | | Name of the role against which the login is being attempted. -|spring.cloud.vault.port | `+++8200+++` | Vault server port. -|spring.cloud.vault.postgresql.backend | `+++postgresql+++` | postgresql backend path. -|spring.cloud.vault.postgresql.enabled | `+++false+++` | Enable postgresql backend usage. -|spring.cloud.vault.postgresql.password-property | `+++spring.datasource.password+++` | Target property for the obtained username. -|spring.cloud.vault.postgresql.role | | Role name for credentials. -|spring.cloud.vault.postgresql.username-property | `+++spring.datasource.username+++` | Target property for the obtained username. -|spring.cloud.vault.rabbitmq.backend | `+++rabbitmq+++` | rabbitmq backend path. -|spring.cloud.vault.rabbitmq.enabled | `+++false+++` | Enable rabbitmq backend usage. -|spring.cloud.vault.rabbitmq.password-property | `+++spring.rabbitmq.password+++` | Target property for the obtained password. -|spring.cloud.vault.rabbitmq.role | | Role name for credentials. -|spring.cloud.vault.rabbitmq.username-property | `+++spring.rabbitmq.username+++` | Target property for the obtained username. -|spring.cloud.vault.reactive.enabled | `+++true+++` | Flag to indicate that reactive discovery is enabled -|spring.cloud.vault.read-timeout | `+++15000+++` | Read timeout. -|spring.cloud.vault.scheme | `+++https+++` | Protocol scheme. Can be either "http" or "https". -|spring.cloud.vault.session.lifecycle.enabled | `+++true+++` | Enable session lifecycle management. -|spring.cloud.vault.session.lifecycle.expiry-threshold | `+++7s+++` | The expiry threshold for a {@link LoginToken}. The threshold represents a minimum TTL duration to consider a login token as valid. Tokens with a shorter TTL are considered expired and are not used anymore. Should be greater than {@code refreshBeforeExpiry} to prevent token expiry. -|spring.cloud.vault.session.lifecycle.refresh-before-expiry | `+++5s+++` | The time period that is at least required before renewing the {@link LoginToken}. -|spring.cloud.vault.ssl.cert-auth-path | `+++cert+++` | Mount path of the TLS cert authentication backend. -|spring.cloud.vault.ssl.enabled-cipher-suites | | List of enabled SSL/TLS cipher suites. @since 3.0.2 -|spring.cloud.vault.ssl.enabled-protocols | | List of enabled SSL/TLS protocol. @since 3.0.2 -|spring.cloud.vault.ssl.key-store | | Trust store that holds certificates and private keys. -|spring.cloud.vault.ssl.key-store-password | | Password used to access the key store. -|spring.cloud.vault.ssl.key-store-type | | Type of the key store. @since 3.0 -|spring.cloud.vault.ssl.trust-store | | Trust store that holds SSL certificates. -|spring.cloud.vault.ssl.trust-store-password | | Password used to access the trust store. -|spring.cloud.vault.ssl.trust-store-type | | Type of the trust store. @since 3.0 -|spring.cloud.vault.token | | Static vault token. Required if {@link #authentication} is {@code TOKEN}. -|spring.cloud.vault.uri | | Vault URI. Can be set with scheme, host and port. - -|=== diff --git a/docs/modules/ROOT/pages/appendix.adoc b/docs/modules/ROOT/pages/appendix.adoc deleted file mode 100644 index eef1c905..00000000 --- a/docs/modules/ROOT/pages/appendix.adoc +++ /dev/null @@ -1,13 +0,0 @@ -:numbered!: -[appendix] -[[common-application-properties]] -= Common application properties -:page-section-summary-toc: 1 - - -Various properties can be specified inside your `application.properties` file, inside your `application.yml` file, or as command line switches. -This appendix provides a list of common {project-full-name} properties and references to the underlying classes that consume them. - -NOTE: Property contributions can come from additional jar files on your classpath, so you should not consider this an exhaustive list. -Also, you can define your own properties. - diff --git a/docs/modules/ROOT/pages/authentication.adoc b/docs/modules/ROOT/pages/authentication.adoc deleted file mode 100644 index e6bb7e6d..00000000 --- a/docs/modules/ROOT/pages/authentication.adoc +++ /dev/null @@ -1,725 +0,0 @@ -[[vault.config.authentication]] -= Authentication methods - -Different organizations have different requirements for security and authentication. -Vault reflects that need by shipping multiple authentication methods. -Spring Cloud Vault supports token and AppId authentication. - -[[vault.config.authentication.token]] -== Token authentication - -Tokens are the core method for authentication within Vault. -Token authentication requires a static token to be provided using the configuration. -As a fallback, the token may also be retrieved from `~/.vault-token` which is the default location used by the Vault CLI to cache tokens. - -NOTE: Token authentication is the default authentication method. -If a token is disclosed an unintended party gains access to Vault and can access secrets for the intended client. - -.application.yml -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: TOKEN - token: 00000000-0000-0000-0000-000000000000 ----- -==== - -* `authentication` setting this value to `TOKEN` selects the Token authentication method -* `token` sets the static token to use. If missing or empty, then an attempt will be made to retrieve a token from ~/.vault-token. - -See also: - -* https://www.vaultproject.io/docs/concepts/tokens.html[Vault Documentation: Tokens] -* https://www.vaultproject.io/docs/commands/login[Vault Documentation: CLI login] -* https://www.vaultproject.io/docs/commands/token-helper[Vault Documentation: CLI default to ~/.vault-token] - -[[vault.config.authentication.vault-agent]] -== Vault Agent authentication - -Vault ships a sidecar utility with Vault Agent since version 0.11.0. Vault Agent implements the functionality of Spring Vault's `SessionManager` -with its Auto-Auth feature. -Applications can reuse cached session credentials by relying on Vault Agent running on `localhost`. -Spring Vault can send requests without the -`X-Vault-Token` header. -Disable Spring Vault's authentication infrastructure to disable client authentication and session management. - -.application.yml -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: NONE ----- -==== - -* `authentication` setting this value to `NONE` disables `ClientAuthentication` -and `SessionManager`. - -See also: https://www.vaultproject.io/docs/agent/index.html[Vault Documentation: Agent] - -[[vault.config.authentication.appid]] -== AppId authentication - -Vault supports https://www.vaultproject.io/docs/auth/app-id.html[AppId] -authentication that consists of two hard to guess tokens. -The AppId defaults to `spring.application.name` that is statically configured. -The second token is the UserId which is a part determined by the application, usually related to the runtime environment. -IP address, Mac address or a Docker container name are good examples. -Spring Cloud Vault Config supports IP address, Mac address and static UserId's (e.g. supplied via System properties). -The IP and Mac address are represented as Hex-encoded SHA256 hash. - -IP address-based UserId's use the local host's IP address. - -.application.yml using SHA256 IP-Address UserId's -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: APPID - app-id: - user-id: IP_ADDRESS ----- -==== - -* `authentication` setting this value to `APPID` selects the AppId authentication method -* `app-id-path` sets the path of the AppId mount to use -* `user-id` sets the UserId method. -Possible values are `IP_ADDRESS`, -`MAC_ADDRESS` or a class name implementing a custom `AppIdUserIdMechanism` - -The corresponding command to generate the IP address UserId from a command line is: - ----- -$ echo -n 192.168.99.1 | sha256sum ----- - -NOTE: Including the line break of `echo` leads to a different hash value so make sure to include the `-n` flag. - -Mac address-based UserId's obtain their network device from the localhost-bound device. -The configuration also allows specifying a `network-interface` hint to pick the right device. -The value of -`network-interface` is optional and can be either an interface name or interface index (0-based). - -.application.yml using SHA256 Mac-Address UserId's -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: APPID - app-id: - user-id: MAC_ADDRESS - network-interface: eth0 ----- -==== - -* `network-interface` sets network interface to obtain the physical address - - -The corresponding command to generate the IP address UserId from a command line is: - ----- -$ echo -n 0AFEDE1234AC | sha256sum ----- - -NOTE: The Mac address is specified uppercase and without colons. -Including the line break of `echo` leads to a different hash value so make sure to include the `-n` flag. - -[[custom-userid]] -=== Custom UserId - -The UserId generation is an open mechanism. -You can set -`spring.cloud.vault.app-id.user-id` to any string and the configured value will be used as static UserId. - -A more advanced approach lets you set `spring.cloud.vault.app-id.user-id` to a classname. -This class must be on your classpath and must implement the `org.springframework.cloud.vault.AppIdUserIdMechanism` interface and the `createUserId` method. -Spring Cloud Vault will obtain the UserId by calling `createUserId` each time it authenticates using AppId to obtain a token. - -.application.yml -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: APPID - app-id: - user-id: com.examlple.MyUserIdMechanism ----- -==== - -.MyUserIdMechanism.java -==== -[source,yaml] ----- -public class MyUserIdMechanism implements AppIdUserIdMechanism { - - @Override - public String createUserId() { - String userId = ... - return userId; - } -} ----- -==== - -See also: https://www.vaultproject.io/docs/auth/app-id.html[Vault Documentation: Using the App ID auth backend] - -[[approle-authentication]] -== AppRole authentication - -https://www.vaultproject.io/docs/auth/app-id.html[AppRole] is intended for machine authentication, like the deprecated (since Vault 0.6.1) xref:authentication.adoc#vault.config.authentication.appid[AppId authentication]. -AppRole authentication consists of two hard to guess (secret) tokens: RoleId and SecretId. - -Spring Vault supports various AppRole scenarios (push/pull mode and wrapped). - -RoleId and optionally SecretId must be provided by configuration, Spring Vault will not look up these or create a custom SecretId. - -.application.yml with AppRole authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: APPROLE - app-role: - role-id: bde2076b-cccb-3cf0-d57e-bca7b1e83a52 ----- -==== - -The following scenarios are supported along the required configuration details: - -.Configuration -|=== -| *Method* | *RoleId* | *SecretId*| *RoleName* | *Token* -| Provided RoleId/SecretId | Provided | Provided | | -| Provided RoleId without SecretId | Provided | | | -| Provided RoleId, Pull SecretId | Provided | | Provided | Provided -| Pull RoleId, provided SecretId | | Provided | Provided | Provided -| Full Pull Mode | | | Provided | Provided -| Wrapped | | | | Provided -| Wrapped RoleId, provided SecretId | | Provided | | Provided -| Provided RoleId, wrapped SecretId | Provided | | | Provided -|=== - -.Pull/Push/Wrapped Matrix -|=== -| *RoleId* | *SecretId* | *Supported* -| Provided | Provided | ✅ -| Provided | Pull | ✅ -| Provided | Wrapped | ✅ -| Provided | Absent | ✅ -| Pull | Provided | ✅ -| Pull | Pull | ✅ -| Pull | Wrapped | ❌ -| Pull | Absent | ❌ -| Wrapped | Provided | ✅ -| Wrapped | Pull | ❌ -| Wrapped | Wrapped | ✅ -| Wrapped | Absent | ❌ -|=== - -NOTE: You can use still all combinations of push/pull/wrapped modes by providing a configured `AppRoleAuthentication` bean within the context. -Spring Cloud Vault cannot derive all possible AppRole combinations from the configuration properties. - -IMPORTANT: AppRole authentication is limited to simple pull mode using reactive infrastructure. -Full pull mode is not yet supported. -Using Spring Cloud Vault with the Spring WebFlux stack enables Vault's reactive auto-configuration which can be disabled by setting `spring.cloud.vault.reactive.enabled=false`. - -.application.yml with all AppRole authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: APPROLE - app-role: - role-id: bde2076b-cccb-3cf0-d57e-bca7b1e83a52 - secret-id: 1696536f-1976-73b1-b241-0b4213908d39 - role: my-role - app-role-path: approle ----- -==== - -* `role-id` sets the RoleId. -* `secret-id` sets the SecretId. -SecretId can be omitted if AppRole is configured without requiring SecretId (See `bind_secret_id`). -* `role`: sets the AppRole name for pull mode. -* `app-role-path` sets the path of the approle authentication mount to use. - -See also: https://www.vaultproject.io/docs/auth/approle.html[Vault Documentation: Using the AppRole auth backend] - -[[vault.config.authentication.awsec2]] -== AWS-EC2 authentication - -The https://www.vaultproject.io/docs/auth/aws-ec2.html[aws-ec2] -auth backend provides a secure introduction mechanism for AWS EC2 instances, allowing automated retrieval of a Vault token. -Unlike most Vault authentication backends, this backend does not require first-deploying, or provisioning security-sensitive credentials (tokens, username/password, client certificates, etc.). -Instead, it treats AWS as a Trusted Third Party and uses the cryptographically signed dynamic metadata information that uniquely represents each EC2 instance. - -.application.yml using AWS-EC2 Authentication -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: AWS_EC2 ----- -==== - -AWS-EC2 authentication enables nonce by default to follow the Trust On First Use (TOFU) principle. -Any unintended party that gains access to the PKCS#7 identity metadata can authenticate against Vault. - -During the first login, Spring Cloud Vault generates a nonce that is stored in the auth backend aside the instance Id. -Re-authentication requires the same nonce to be sent. -Any other party does not have the nonce and can raise an alert in Vault for further investigation. - -The nonce is kept in memory and is lost during application restart. -You can configure a static nonce with `spring.cloud.vault.aws-ec2.nonce`. - -AWS-EC2 authentication roles are optional and default to the AMI. -You can configure the authentication role by setting the -`spring.cloud.vault.aws-ec2.role` property. - -.application.yml with configured role -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: AWS_EC2 - aws-ec2: - role: application-server ----- -==== - -.application.yml with all AWS EC2 authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: AWS_EC2 - aws-ec2: - role: application-server - aws-ec2-path: aws-ec2 - identity-document: http://... - nonce: my-static-nonce ----- -==== - -* `authentication` setting this value to `AWS_EC2` selects the AWS EC2 authentication method -* `role` sets the name of the role against which the login is being attempted. -* `aws-ec2-path` sets the path of the AWS EC2 mount to use -* `identity-document` sets URL of the PKCS#7 AWS EC2 identity document -* `nonce` used for AWS-EC2 authentication. -An empty nonce defaults to nonce generation - -See also: https://www.vaultproject.io/docs/auth/aws.html[Vault Documentation: Using the aws auth backend] - -[[vault.config.authentication.awsiam]] -== AWS-IAM authentication - -The https://www.vaultproject.io/docs/auth/aws-ec2.html[aws] backend provides a secure authentication mechanism for AWS IAM roles, allowing the automatic authentication with vault based on the current IAM role of the running application. -Unlike most Vault authentication backends, this backend does not require first-deploying, or provisioning security-sensitive credentials (tokens, username/password, client certificates, etc.). -Instead, it treats AWS as a Trusted Third Party and uses the 4 pieces of information signed by the caller with their IAM credentials to verify that the caller is indeed using that IAM role. - -The current IAM role the application is running in is automatically calculated. -If you are running your application on AWS ECS then the application will use the IAM role assigned to the ECS task of the running container. -If you are running your application naked on top of an EC2 instance then the IAM role used will be the one assigned to the EC2 instance. - -When using the AWS-IAM authentication you must create a role in Vault and assign it to your IAM role. -An empty `role` defaults to the friendly name the current IAM role. - -.application.yml with required AWS-IAM Authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: AWS_IAM ----- -==== - -.application.yml with all AWS-IAM Authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: AWS_IAM - aws-iam: - region: aws-global - role: my-dev-role - aws-path: aws - server-name: some.server.name - endpoint-uri: https://sts.eu-central-1.amazonaws.com ----- -==== - -* `region` sets the name of the AWS region. If not supplied, the region will be determined by AWS defaults. -* `role` sets the name of the role against which the login is being attempted. -This should be bound to your IAM role. -If one is not supplied then the friendly name of the current IAM user will be used as the vault role. -* `aws-path` sets the path of the AWS mount to use -* `server-name` sets the value to use for the `X-Vault-AWS-IAM-Server-ID` header preventing certain types of replay attacks. -* `endpoint-uri` sets the value to use for the AWS STS API used for the `iam_request_url` parameter. - -AWS-IAM requires the AWS Java SDK v2 dependency (`software.amazon.awssdk:auth`) as the authentication implementation uses AWS SDK types for credentials and request signing. - -See also: https://www.vaultproject.io/docs/auth/aws.html[Vault Documentation: Using the aws auth backend] - -[[vault.config.authentication.azuremsi]] -== Azure MSI authentication - -The https://www.vaultproject.io/docs/auth/azure.html[azure] -auth backend provides a secure introduction mechanism for Azure VM instances, allowing automated retrieval of a Vault token. -Unlike most Vault authentication backends, this backend does not require first-deploying, or provisioning security-sensitive credentials (tokens, username/password, client certificates, etc.). -Instead, it treats Azure as a Trusted Third Party and uses the managed service identity and instance metadata information that can be bound to a VM instance. - -.application.yml with required Azure Authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: AZURE_MSI - azure-msi: - role: my-dev-role ----- -==== - -.application.yml with all Azure Authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: AZURE_MSI - azure-msi: - role: my-dev-role - azure-path: azure - metadata-service: http://169.254.169.254/metadata/instance… - identity-token-service: http://169.254.169.254/metadata/identity… ----- -==== - -* `role` sets the name of the role against which the login is being attempted. -* `azure-path` sets the path of the Azure mount to use -* `metadata-service` sets the URI at which to access the instance metadata service -* `identity-token-service` sets the URI at which to access the identity token service - -Azure MSI authentication obtains environmental details about the virtual machine (subscription Id, resource group, VM name) from the instance metadata service. -The Vault server has Resource Id defaults to `https://vault.hashicorp.com`. -To change this, set `spring.cloud.vault.azure-msi.identity-token-service` accordingly. - -See also: - -* https://www.vaultproject.io/docs/auth/azure.html[Vault Documentation: Using the azure auth backend] -* https://docs.microsoft.com/en-us/azure/virtual-machines/windows/instance-metadata-service[Azure Documentation: Azure Instance Metadata Service] - -[[vault.config.authentication.clientcert]] -== TLS certificate authentication - -The `cert` auth backend allows authentication using SSL/TLS client certificates that are either signed by a CA or self-signed. - -To enable `cert` authentication you need to: - -1. Use SSL, see xref:other-topics.adoc#vault.config.ssl[Vault Client SSL configuration] -2. Configure a Java `Keystore` that contains the client certificate and the private key -3. Set the `spring.cloud.vault.authentication` to `CERT` - -.application.yml -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: CERT - ssl: - key-store: classpath:keystore.jks - key-store-password: changeit - key-store-type: JKS - cert-auth-path: cert ----- -==== - -See also: https://www.vaultproject.io/docs/auth/cert.html[Vault Documentation: Using the Cert auth backend] - -[[vault.config.authentication.cubbyhole]] -== Cubbyhole authentication - -Cubbyhole authentication uses Vault primitives to provide a secured authentication workflow. -Cubbyhole authentication uses tokens as primary login method. -An ephemeral token is used to obtain a second, login VaultToken from Vault's Cubbyhole secret backend. -The login token is usually longer-lived and used to interact with Vault. -The login token will be retrieved from a wrapped response stored at `/cubbyhole/response`. - -*Creating a wrapped token* - -NOTE: Response Wrapping for token creation requires Vault 0.6.0 or higher. - -.Creating and storing tokens -==== -[source,shell] ----- -$ vault token-create -wrap-ttl="10m" -Key Value ---- ----- -wrapping_token: 397ccb93-ff6c-b17b-9389-380b01ca2645 -wrapping_token_ttl: 0h10m0s -wrapping_token_creation_time: 2016-09-18 20:29:48.652957077 +0200 CEST -wrapped_accessor: 46b6aebb-187f-932a-26d7-4f3d86a68319 ----- -==== - -.application.yml -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: CUBBYHOLE - token: 397ccb93-ff6c-b17b-9389-380b01ca2645 ----- -==== - -See also: - -* https://www.vaultproject.io/docs/concepts/tokens.html[Vault Documentation: Tokens] -* https://www.vaultproject.io/docs/secrets/cubbyhole/index.html[Vault Documentation: Cubbyhole Secret Backend] -* https://www.vaultproject.io/docs/concepts/response-wrapping.html[Vault Documentation: Response Wrapping] - -[[vault.config.authentication.gcpgce]] -== GCP-GCE authentication - -The https://www.vaultproject.io/docs/auth/gcp.html[gcp] -auth backend allows Vault login by using existing GCP (Google Cloud Platform) IAM and GCE credentials. - -GCP GCE (Google Compute Engine) authentication creates a signature in the form of a JSON Web Token (JWT) for a service account. -A JWT for a Compute Engine instance is obtained from the GCE metadata service using https://cloud.google.com/compute/docs/instances/verifying-instance-identity[Instance identification]. -This API creates a JSON Web Token that can be used to confirm the instance identity. - -Unlike most Vault authentication backends, this backend does not require first-deploying, or provisioning security-sensitive credentials (tokens, username/password, client certificates, etc.). -Instead, it treats GCP as a Trusted Third Party and uses the cryptographically signed dynamic metadata information that uniquely represents each GCP service account. - -.application.yml with required GCP-GCE Authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: GCP_GCE - gcp-gce: - role: my-dev-role ----- -==== - -.application.yml with all GCP-GCE Authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: GCP_GCE - gcp-gce: - gcp-path: gcp - role: my-dev-role - service-account: my-service@projectid.iam.gserviceaccount.com ----- -==== - -* `role` sets the name of the role against which the login is being attempted. -* `gcp-path` sets the path of the GCP mount to use -* `service-account` allows overriding the service account Id to a specific value. -Defaults to the `default` service account. - -See also: - -* https://www.vaultproject.io/docs/auth/gcp.html[Vault Documentation: Using the GCP auth backend] -* https://cloud.google.com/compute/docs/instances/verifying-instance-identity[GCP Documentation: Verifying the Identity of Instances] - -[[vault.config.authentication.gcpiam]] -== GCP-IAM authentication - -The https://www.vaultproject.io/docs/auth/gcp.html[gcp] -auth backend allows Vault login by using existing GCP (Google Cloud Platform) IAM and GCE credentials. - -GCP IAM authentication creates a signature in the form of a JSON Web Token (JWT) for a service account. -A JWT for a service account is obtained by calling GCP IAM's https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signJwt[`projects.serviceAccounts.signJwt`] API. The caller authenticates against GCP IAM and proves thereby its identity. -This Vault backend treats GCP as a Trusted Third Party. - -IAM credentials can be obtained from either the runtime environment , specifically the https://cloud.google.com/docs/authentication/production[`GOOGLE_APPLICATION_CREDENTIALS`] -environment variable, the Google Compute metadata service, or supplied externally as e.g. JSON or base64 encoded. -JSON is the preferred form as it carries the project id and service account identifier required for calling ``projects.serviceAccounts.signJwt``. - -.application.yml with required GCP-IAM Authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: GCP_IAM - gcp-iam: - role: my-dev-role ----- -==== - -.application.yml with all GCP-IAM Authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: GCP_IAM - gcp-iam: - credentials: - location: classpath:credentials.json - encoded-key: e+KApn0= - gcp-path: gcp - jwt-validity: 15m - project-id: my-project-id - role: my-dev-role - service-account-id: my-service@projectid.iam.gserviceaccount.com ----- -==== - -* `role` sets the name of the role against which the login is being attempted. -* `credentials.location` path to the credentials resource that contains Google credentials in JSON format. -* `credentials.encoded-key` the base64 encoded contents of an OAuth2 account private key in the JSON format. -* `gcp-path` sets the path of the GCP mount to use -* `jwt-validity` configures the JWT token validity. -Defaults to 15 minutes. -* `project-id` allows overriding the project Id to a specific value. -Defaults to the project Id from the obtained credential. -* `service-account` allows overriding the service account Id to a specific value. -Defaults to the service account from the obtained credential. - -GCP IAM authentication requires the Google Cloud Java SDK dependency (`com.google.apis:google-api-services-iam` and `com.google.auth:google-auth-library-oauth2-http`) as the authentication implementation uses Google APIs for credentials and JWT signing. - -NOTE: Google credentials require an OAuth 2 token maintaining the token lifecycle. -All API is synchronous therefore, `GcpIamAuthentication` does not support `AuthenticationSteps` which is required for reactive usage. - -See also: - -* https://www.vaultproject.io/docs/auth/gcp.html[Vault Documentation: Using the GCP auth backend] -* https://cloud.google.com/iam/reference/rest/v1/projects.serviceAccounts/signJwt[GCP Documentation: projects.serviceAccounts.signJwt] - -[[vault.authentication.gcpiam]] -[[vault.config.authentication.kubernetes]] -== Kubernetes authentication - -Kubernetes authentication mechanism (since Vault 0.8.3) allows to authenticate with Vault using a Kubernetes Service Account Token. -The authentication is role based and the role is bound to a service account name and a namespace. - -A file containing a JWT token for a pod’s service account is automatically mounted at `/var/run/secrets/kubernetes.io/serviceaccount/token`. - -.application.yml with all Kubernetes authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: KUBERNETES - kubernetes: - role: my-dev-role - kubernetes-path: kubernetes - service-account-token-file: /var/run/secrets/kubernetes.io/serviceaccount/token ----- -==== - -* `role` sets the Role. -* `kubernetes-path` sets the path of the Kubernetes mount to use. -* `service-account-token-file` sets the location of the file containing the Kubernetes Service Account Token. -Defaults to `/var/run/secrets/kubernetes.io/serviceaccount/token`. - -See also: - -* https://www.vaultproject.io/docs/auth/kubernetes.html[Vault Documentation: Kubernetes] -* https://kubernetes.io/docs/tasks/configure-pod-container/configure-service-account/[Kubernetes Documentation: Configure Service Accounts for Pods] - -[[vault.config.authentication.pcf]] -== Pivotal CloudFoundry authentication - -The https://www.vaultproject.io/docs/auth/pcf.html[pcf] -auth backend provides a secure introduction mechanism for applications running within Pivotal's CloudFoundry instances allowing automated retrieval of a Vault token. -Unlike most Vault authentication backends, this backend does not require first-deploying, or provisioning security-sensitive credentials (tokens, username/password, client certificates, etc.) as identity provisioning is handled by PCF itself. -Instead, it treats PCF as a Trusted Third Party and uses the managed instance identity. - -.application.yml with required PCF Authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: PCF - pcf: - role: my-dev-role ----- -==== - -.application.yml with all PCF Authentication properties -==== -[source,yaml] ----- -spring.cloud.vault: - authentication: PCF - pcf: - role: my-dev-role - pcf-path: path - instance-certificate: /etc/cf-instance-credentials/instance.crt - instance-key: /etc/cf-instance-credentials/instance.key ----- -==== - -* `role` sets the name of the role against which the login is being attempted. -* `pcf-path` sets the path of the PCF mount to use. -* `instance-certificate` sets the path to the PCF instance identity certificate. -Defaults to `${CF_INSTANCE_CERT}` env variable. -* `instance-key` sets the path to the PCF instance identity key. -Defaults to `${CF_INSTANCE_KEY}` env variable. - -NOTE: PCF authentication requires BouncyCastle (bcpkix-jdk15on) to be on the classpath for RSA PSS signing. - -See also: https://www.vaultproject.io/docs/auth/pcf.html[Vault Documentation: Using the pcf auth backend] - -[[vault.config.acl]] -= ACL Requirements - -This section explains which paths are accessed by Spring Vault so you can derive your policy declarations from the required capabilities. - -|=== -|Capability |Associated HTTP verbs - -|create -|`POST`/`PUT` - -|read -|`GET` - -|update -|`POST`/`PUT` - -|delete -|`DELETE` - -|list -|`LIST` (`GET`) -|=== - - -See also https://www.vaultproject.io/guides/identity/policies. - -[[authentication]] -== Authentication - -Login: `POST auth/$authMethod/login` - -[[keyvalue-mount-discovery]] -== KeyValue Mount Discovery - -`GET sys/internal/ui/mounts/$mountPath` - -[[secretleasecontainer]] -== SecretLeaseContainer - -`SecretLeaseContainer` uses different paths depending on the configured lease endpoint. - -`LeaseEndpoints.Legacy` - -* Revocation: `PUT sys/revoke` -* Renewal: `PUT sys/renew` - -`LeaseEndpoints.Leases` (`SysLeases`) - -* Revocation: `PUT sys/leases/revoke` -* Renewal: `PUT sys/leases/renew` - -[[session-management]] -== Session Management - -* Token lookup: `GET auth/token/lookup-self` -* Renewal: `POST auth/token/renew-self` -* Revoke: `POST auth/token/revoke-self` diff --git a/docs/modules/ROOT/pages/config-data.adoc b/docs/modules/ROOT/pages/config-data.adoc deleted file mode 100644 index 49c0fdff..00000000 --- a/docs/modules/ROOT/pages/config-data.adoc +++ /dev/null @@ -1,112 +0,0 @@ -[[vault.configdata]] -= ConfigData API - -Spring Boot provides since version 2.4 a ConfigData API that allows the declaration of configuration sources and importing these as property sources. - -Spring Cloud Vault uses as of version 3.0 the ConfigData API to mount Vault's secret backends as property sources. -In previous versions, the Bootstrap context was used. -The ConfigData API is much more flexible as it allows specifying which configuration systems to import and in which order. - -NOTE: You can enable the bootstrap context either by setting the configuration property `spring.cloud.bootstrap.enabled=true` or by including the dependency `org.springframework.cloud:spring-cloud-starter-bootstrap`. -Using the boostrap context should be only rarely required hence we recommend using the Config Data API for more flexibility regarding property source ordering. - -[[vault.configdata.locations]] -== ConfigData Locations - -You can mount Vault configuration through one or more `PropertySource` that are materialized from Vault. -Spring Cloud Vault supports two config locations: - -* `vault://` (default location) -* `vault:///` (contextual location) - -Using the default location mounts property sources for all enabled xref:secret-backends.adoc[Secret Backends]. -Without further configuration, Spring Cloud Vault mounts the key-value backend at `/secret/${spring.application.name}`. -Each activated profile adds another context path following the form `/secret/${spring.application.name}/${profile}`. -Adding further modules to the classpath, such as `spring-cloud-config-databases`, provides additional secret backend configuration options which get mounted as property sources if enabled. - -If you want to control which context paths are mounted from Vault as `PropertySource`, you can either use a contextual location (`vault:///my/context/path`) or configure a xref:secret-backends.adoc#vault.config.backends.configurer[`VaultConfigurer`]. - -Contextual locations are specified and mounted individually. -Spring Cloud Vault mounts each location as a unique `PropertySource`. -You can mix the default locations with contextual locations (or other config systems) to control the order of property sources. -This approach is useful in particular if you want to disable the default key-value path computation and mount each key-value backend yourself instead. - -.application.yml -==== -[source,yaml] ----- -spring.config.import: vault://first/context/path, vault://other/path, vault:// ----- -==== - -Property names within a Spring `Environment` must be unique to avoid shadowing. -If you use the same secret names in different context paths and you want to expose these as individual properties you can distinguish them by adding a `prefix` query parameter to the location. - -.application.yml -==== -[source,yaml] ----- -spring.config.import: vault://my/path?prefix=foo., vault://my/other/path?prefix=bar. -secret: ${foo.secret} -other.secret: ${bar.secret} ----- - -NOTE: Prefixes are added as-is to all property names returned by Vault. If you want key names to be separated with a dot between the prefix and key name, make sure to add a trailing dot to the prefix. - -==== - -[[vault.configdata.location.optional]] -== Conditionally enable/disable Vault Configuration - -In some cases, it can be required to launch an application without Vault. You can express whether a Vault config location should be optional or mandatory (default) through the location string: - -* `optional:vault://` (default location) -* `optional:vault:///` (contextual location) - -Optional locations are skipped during application startup if Vault support was disabled through `spring.cloud.vault.enabled=false`. - -NOTE: Vault context paths that cannot be found (HTTP Status 404) are skipped regardless of whether the config location is marked optional. xref:other-topics.adoc#vault.config.fail-fast[Vault Client Fail Fast] allows failing on start if a Vault context path cannot be found because of HTTP Status 404. - - -[[vault.configdata.customization]] -== Infrastructure Customization - -Spring Cloud Vault requires infrastructure classes to interact with Vault. When not using the ConfigData API (meaning that you haven't specified `spring.config.import=vault://` or a contextual Vault path), Spring Cloud Vault defines its beans through `VaultAutoConfiguration` and `VaultReactiveAutoConfiguration`. -Spring Boot bootstraps the application before a Spring Context is available. Therefore `VaultConfigDataLoader` registers beans itself to propagate these later on into the application context. - -You can customize the infrastructure used by Spring Cloud Vault by registering custom instances using the `Bootstrapper` API: - -.Customizing `ClientHttpRequestFactory` -==== -[source,java] ----- -ClientOptions options = new ClientOptions(); -SslConfiguration sslConfiguration = SslConfiguration.unconfigured(); -HttpClientBuilder builder = HttpComponents.getHttpClientBuilder(options, sslConfiguration); - -InstanceSupplier supplier = context -> -new ClientFactoryWrapper(new HttpComponentsClientHttpRequestFactory(builder.build())); - -SpringApplication application = new SpringApplication(MyApplication.class); -application.addBootstrapRegistryInitializer(registry -> registry.register(ClientFactoryWrapper.class, supplier)); ----- -==== - -.Customizing `RestTemplateBuilder` -==== -[source,java] ----- -InstanceSupplier supplier = context -> { - - return RestTemplateBuilder - .builder() - .requestFactory(context.get(ClientFactoryWrapper.class).getClientHttpRequestFactory()) - .defaultHeader("X-Vault-Namespace", "my-namespace"); -}; - -SpringApplication application = new SpringApplication(MyApplication.class); -application.addBootstrapRegistryInitializer(registry -> registry.register(RestTemplateBuilder.class, supplier)); ----- -==== - -See also xref:secret-backends.adoc#vault.config.backends.configurer[Customize which secret backends to expose as PropertySource] and the source of `VaultConfigDataLoader` for customization hooks. diff --git a/docs/modules/ROOT/pages/index.adoc b/docs/modules/ROOT/pages/index.adoc deleted file mode 120000 index 7d4aae93..00000000 --- a/docs/modules/ROOT/pages/index.adoc +++ /dev/null @@ -1 +0,0 @@ -spring-cloud-vault.adoc \ No newline at end of file diff --git a/docs/modules/ROOT/pages/intro.adoc b/docs/modules/ROOT/pages/intro.adoc deleted file mode 100644 index 9d6514e6..00000000 --- a/docs/modules/ROOT/pages/intro.adoc +++ /dev/null @@ -1,3 +0,0 @@ -Spring Cloud Vault Config provides client-side support for externalized configuration in a distributed system. -With https://www.vaultproject.io[HashiCorp's Vault] you have a central place to manage external secret properties for applications across all environments. -Vault can manage static and dynamic secrets such as username/password for remote applications/resources and provide credentials for external services such as MySQL, PostgreSQL, Apache Cassandra, Couchbase, MongoDB, Consul, AWS and more. diff --git a/docs/modules/ROOT/pages/new-features.adoc b/docs/modules/ROOT/pages/new-features.adoc deleted file mode 100644 index 5865f5ef..00000000 --- a/docs/modules/ROOT/pages/new-features.adoc +++ /dev/null @@ -1,14 +0,0 @@ -[[new-noteworthy]] -= New & Noteworthy -:page-section-summary-toc: 1 - -This section briefly covers items that are new and noteworthy in the latest releases. - -[[new-in-3.0.0]] -== New in Spring Cloud Vault 3.0 - -* Migration of `PropertySource` initialization from Spring Cloud's Bootstrap Context to Spring Boot's xref:config-data.adoc[ConfigData API]. -* Support for the xref:secret-backends.adoc#vault.config.backends.couchbase[Couchbase Database] backend. -* Configuration of keystore/truststore types through `spring.cloud.vault.ssl.key-store-type=…`/`spring.cloud.vault.ssl.trust-store-type=…` including PEM support. -* Support for `ReactiveDiscoveryClient` by configuring a `ReactiveVaultEndpointProvider`. -* Support to configure xref:secret-backends.adoc#vault.config.backends.databases[Multiple Databases]. diff --git a/docs/modules/ROOT/pages/other-topics.adoc b/docs/modules/ROOT/pages/other-topics.adoc deleted file mode 100644 index 805e8df6..00000000 --- a/docs/modules/ROOT/pages/other-topics.adoc +++ /dev/null @@ -1,173 +0,0 @@ -[[service-registry-configuration]] -= Service Registry Configuration - -You can use a `DiscoveryClient` (such as from Spring Cloud Consul) to locate a Vault server by setting spring.cloud.vault.discovery.enabled=true (default `false`). -The net result of that is that your apps need a application.yml (or an environment variable) with the appropriate discovery configuration. -The benefit is that the Vault can change its co-ordinates, as long as the discovery service is a fixed point. -The default service id is `vault` but you can change that on the client with -`spring.cloud.vault.discovery.serviceId`. - -The discovery client implementations all support some kind of metadata map (e.g. for Eureka we have eureka.instance.metadataMap). -Some additional properties of the service may need to be configured in its service registration metadata so that clients can connect correctly. -Service registries that do not provide details about transport layer security need to provide a `scheme` metadata entry to be set either to `https` or `http`. -If no scheme is configured and the service is not exposed as secure service, then configuration defaults to `spring.cloud.vault.scheme` which is `https` when it's not set. - -==== -[source,yaml] ----- -spring.cloud.vault.discovery: - enabled: true - service-id: my-vault-service ----- -==== - -[[vault.config.fail-fast]] -= Vault Client Fail Fast - -In some cases, it may be desirable to fail startup of a service if it cannot connect to the Vault Server. -If this is the desired behavior, set the bootstrap configuration property -`spring.cloud.vault.fail-fast=true` and the client will halt with an Exception. - -==== -[source,yaml] ----- -spring.cloud.vault: - fail-fast: true ----- -==== - -[[vault.config.namespaces]] -= Vault Enterprise Namespace Support - -Vault Enterprise allows using namespaces to isolate multiple Vaults on a single Vault server. -Configuring a namespace by setting -`spring.cloud.vault.namespace=…` enables the namespace header -`X-Vault-Namespace` on every outgoing HTTP request when using the Vault -`RestTemplate` or `WebClient`. - -Please note that this feature is not supported by Vault Community edition and has no effect on Vault operations. - -==== -[source,yaml] ----- -spring.cloud.vault: - namespace: my-namespace ----- -==== - -See also: https://www.vaultproject.io/docs/enterprise/namespaces/index.html[Vault Enterprise: Namespaces] - -[[vault.config.ssl]] -= Vault Client SSL configuration - -SSL can be configured declaratively by setting various properties. -You can set either `javax.net.ssl.trustStore` to configure JVM-wide SSL settings or `spring.cloud.vault.ssl.trust-store` -to set SSL settings only for Spring Cloud Vault Config. - -==== -[source,yaml] ----- -spring.cloud.vault: - ssl: - trust-store: classpath:keystore.jks - trust-store-password: changeit - trust-store-type: JKS - enabled-protocols: TLSv1.2,TLSv1.3 - enabled-cipher-suites: TLS_AES_128_GCM_SHA256 ----- -==== - -* `trust-store` sets the resource for the trust-store. -SSL-secured Vault communication will validate the Vault SSL certificate with the specified trust-store. -* `trust-store-password` sets the trust-store password -* `trust-store-type` sets the trust-store type. Supported values are all supported `KeyStore` types including `PEM`. -* `enabled-protocols` sets the list of enabled SSL/TLS protocols (since 3.0.2). -* `enabled-cipher-suites` sets the list of enabled SSL/TLS cipher suites (since 3.0.2). - -Please note that configuring `spring.cloud.vault.ssl.*` can be only applied when either Apache Http Components or the OkHttp client is on your class-path. - -[[vault-lease-renewal]] -= Lease lifecycle management (renewal and revocation) - -With every secret, Vault creates a lease: -metadata containing information such as a time duration, renewability, and more. - -Vault promises that the data will be valid for the given duration, or Time To Live (TTL). -Once the lease is expired, Vault can revoke the data, and the consumer of the secret can no longer be certain that it is valid. - -Spring Cloud Vault maintains a lease lifecycle beyond the creation of login tokens and secrets. -That said, login tokens and secrets associated with a lease are scheduled for renewal just before the lease expires until terminal expiry. -Application shutdown revokes obtained login tokens and renewable leases. - -Secret service and database backends (such as MongoDB or MySQL) usually generate a renewable lease so generated credentials will be disabled on application shutdown. - -NOTE: Static tokens are not renewed or revoked. - -Lease renewal and revocation is enabled by default and can be disabled by setting `spring.cloud.vault.config.lifecycle.enabled` -to `false`. -This is not recommended as leases can expire and Spring Cloud Vault cannot longer access Vault or services using generated credentials and valid credentials remain active after application shutdown. - -==== -[source,yaml] ----- -spring.cloud.vault: - config.lifecycle: - enabled: true - min-renewal: 10s - expiry-threshold: 1m - lease-endpoints: Legacy - ----- -==== - -* `enabled` controls whether leases associated with secrets are considered to be renewed and expired secrets are rotated. -Enabled by default. -* `min-renewal` sets the duration that is at least required before renewing a lease. -This setting prevents renewals from happening too often. -* `expiry-threshold` sets the expiry threshold. -A lease is renewed the configured period of time before it expires. -* `lease-endpoints` sets the endpoints for renew and revoke. -Legacy for vault versions before 0.8 and SysLeases for later. - -See also: https://www.vaultproject.io/docs/concepts/lease.html[Vault Documentation: Lease, Renew, and Revoke] - -[[vault-session-lifecycle]] -= Session token lifecycle management (renewal, re-login and revocation) - -A Vault session token (also referred to as `LoginToken`) is quite similar to a lease as it has a TTL, max TTL, and may expire. -Once a login token expires, it cannot be used anymore to interact with Vault. -Therefore, Spring Vault ships with a `SessionManager` API for imperative and reactive use. - -Spring Cloud Vault maintains the session token lifecycle by default. -Session tokens are obtained lazily so the actual login is deferred until the first session-bound use of Vault. -Once Spring Cloud Vault obtains a session token, it retains it until expiry. -The next time a session-bound activity is used, Spring Cloud Vault re-logins into Vault and obtains a new session token. -On application shut down, Spring Cloud Vault revokes the token if it was still active to terminate the session. - -Session lifecycle is enabled by default and can be disabled by setting `spring.cloud.vault.session.lifecycle.enabled` -to `false`. -Disabling is not recommended as session tokens can expire and Spring Cloud Vault cannot longer access Vault. - -==== -[source,yaml] ----- -spring.cloud.vault: - session.lifecycle: - enabled: true - refresh-before-expiry: 10s - expiry-threshold: 20s ----- -==== - -* `enabled` controls whether session lifecycle management is enabled to renew session tokens. -Enabled by default. -* `refresh-before-expiry` controls the point in time when the session token gets renewed. -The refresh time is calculated by subtracting `refresh-before-expiry` from the token expiry time. -Defaults to `5 seconds`. -* `expiry-threshold` sets the expiry threshold. -The threshold represents a minimum TTL duration to consider a session token as valid. -Tokens with a shorter TTL are considered expired and are not used anymore. -Should be greater than `refresh-before-expiry` to prevent token expiry. -Defaults to `7 seconds`. - -See also: https://www.vaultproject.io/api-docs/auth/token#renew-a-token-self[Vault Documentation: Token Renewal] diff --git a/docs/modules/ROOT/pages/quickstart.adoc b/docs/modules/ROOT/pages/quickstart.adoc deleted file mode 100644 index 56e41b41..00000000 --- a/docs/modules/ROOT/pages/quickstart.adoc +++ /dev/null @@ -1,259 +0,0 @@ -:docs: https://cloud.spring.io/spring-cloud-vault/reference/html/ - -*Prerequisites* - -To get started with Vault and this guide you need a *NIX-like operating systems that provides: - -* `wget`, `openssl` and `unzip` -* at least Java 8 and a properly configured `JAVA_HOME` environment variable - -NOTE: This guide explains Vault setup from a Spring Cloud Vault perspective for integration testing. -You can find a getting started guide directly on the Vault project site: https://learn.hashicorp.com/vault - -*Install Vault* - -[source,bash] ----- -$ wget https://releases.hashicorp.com/vault/${vault_version}/vault_${vault_version}_${platform}.zip -$ unzip vault_${vault_version}_${platform}.zip ----- - -NOTE: These steps can be achieved by downloading and running https://github.com/spring-cloud/spring-cloud-vault/blob/master/src/test/bash/install_vault.sh[`install_vault.sh`]. - -*Create SSL certificates for Vault* - -Next, you'r required to generate a set of certificates: - -* Root CA -* Vault Certificate (decrypted key `work/ca/private/localhost.decrypted.key.pem` and certificate `work/ca/certs/localhost.cert.pem`) - -Make sure to import the Root Certificate into a Java-compliant truststore. - -The easiest way to achieve this is by using OpenSSL. - -NOTE: https://github.com/spring-cloud/spring-cloud-vault/blob/master/src/test/bash/[`create_certificates.sh`] creates certificates in `work/ca` and a JKS truststore `work/keystore.jks`. -If you want to run Spring Cloud Vault using this quickstart guide you need to configure the truststore the `spring.cloud.vault.ssl.trust-store` property to `file:work/keystore.jks`. - -[[quickstart.vault.start]] -*Start Vault server* - -Next create a config file along the lines of: - -[source] ----- -backend "inmem" { -} - -listener "tcp" { - address = "0.0.0.0:8200" - tls_cert_file = "work/ca/certs/localhost.cert.pem" - tls_key_file = "work/ca/private/localhost.decrypted.key.pem" -} - -disable_mlock = true ----- - -NOTE: You can find an example config file at https://github.com/spring-clod/spring-cloud-vault/blob/master/src/test/bash/vault.conf[`vault.conf`]. - -[source,bash] ----- -$ vault server -config=vault.conf ----- - -Vault is started listening on `0.0.0.0:8200` using the `inmem` storage and `https`. -Vault is sealed and not initialized when starting up. - -NOTE: If you want to run tests, leave Vault uninitialized. -The tests will initialize Vault and create a root token `00000000-0000-0000-0000-000000000000`. - -If you want to use Vault for your application or give it a try then you need to initialize it first. - -[source,bash] ----- -$ export VAULT_ADDR="https://localhost:8200" -$ export VAULT_SKIP_VERIFY=true # Don't do this for production -$ vault operator init ----- - -You should see something like: - -[source,bash] ----- -Key 1: 7149c6a2e16b8833f6eb1e76df03e47f6113a3288b3093faf5033d44f0e70fe701 -Key 2: 901c534c7988c18c20435a85213c683bdcf0efcd82e38e2893779f152978c18c02 -Key 3: 03ff3948575b1165a20c20ee7c3e6edf04f4cdbe0e82dbff5be49c63f98bc03a03 -Key 4: 216ae5cc3ddaf93ceb8e1d15bb9fc3176653f5b738f5f3d1ee00cd7dccbe926e04 -Key 5: b2898fc8130929d569c1677ee69dc5f3be57d7c4b494a6062693ce0b1c4d93d805 -Initial Root Token: 19aefa97-cccc-bbbb-aaaa-225940e63d76 - -Vault initialized with 5 keys and a key threshold of 3. Please -securely distribute the above keys. When the Vault is re-sealed, -restarted, or stopped, you must provide at least 3 of these keys -to unseal it again. - -Vault does not store the master key. Without at least 3 keys, -your Vault will remain permanently sealed. ----- - -Vault will initialize and return a set of unsealing keys and the root token. -Pick 3 keys and unseal Vault. -Store the Vault token in the `VAULT_TOKEN` -environment variable. - -[source,bash] ----- -$ vault operator unseal (Key 1) -$ vault operator unseal (Key 2) -$ vault operator unseal (Key 3) -$ export VAULT_TOKEN=(Root token) -# Required to run Spring Cloud Vault tests after manual initialization -$ vault token create -id="00000000-0000-0000-0000-000000000000" -policy="root" ----- - -Spring Cloud Vault accesses different resources. -By default, the secret backend is enabled which accesses secret config settings via JSON endpoints. - -The HTTP service has resources in the form: - ----- -/secret/{application}/{profile} -/secret/{application} -/secret/{defaultContext}/{profile} -/secret/{defaultContext} ----- - -where the "application" is injected as the `spring.application.name` in the -`SpringApplication` (i.e. what is normally "application" in a regular Spring Boot app), "profile" is an active profile (or comma-separated list of properties). -Properties retrieved from Vault will be used "as-is" without further prefixing of the property names. - -[[client-side-usage]] -= Client Side Usage - -To use these features in an application, just build it as a Spring Boot application that depends on `spring-cloud-vault-config` (e.g. see the test cases). -Example Maven configuration: - -.pom.xml -==== -[source,xml,indent=0,subs="verbatim,quotes,attributes"] ----- - - org.springframework.boot - spring-boot-starter-parent - 2.4.0.RELEASE - - - - - - org.springframework.cloud - spring-cloud-starter-vault-config - {project-version} - - - org.springframework.boot - spring-boot-starter-test - test - - - - - - - org.springframework.boot - spring-boot-maven-plugin - - - - - ----- -==== - -Then you can create a standard Spring Boot application, like this simple HTTP server: - -==== -[source,java] ----- -@SpringBootApplication -@RestController -public class Application { - - @RequestMapping("/") - public String home() { - return "Hello World!"; - } - - public static void main(String[] args) { - SpringApplication.run(Application.class, args); - } -} ----- -==== - -When it runs it will pick up the external configuration from the default local Vault server on port `8200` if it is running. -To modify the startup behavior you can change the location of the Vault server using `application.properties`, for example - -.application.yml -==== -[source,yaml] ----- -spring.cloud.vault: - host: localhost - port: 8200 - scheme: https - uri: https://localhost:8200 - connection-timeout: 5000 - read-timeout: 15000 - config: -spring.config.import: vault:// ----- -==== - -* `host` sets the hostname of the Vault host. -The host name will be used for SSL certificate validation -* `port` sets the Vault port -* `scheme` setting the scheme to `http` will use plain HTTP. -Supported schemes are `http` and `https`. -* `uri` configure the Vault endpoint with an URI. Takes precedence over host/port/scheme configuration -* `connection-timeout` sets the connection timeout in milliseconds -* `read-timeout` sets the read timeout in milliseconds -* `spring.config.import` mounts Vault as `PropertySource` using all enabled secret backends (key-value enabled by default) - -Enabling further integrations requires additional dependencies and configuration. -Depending on how you have set up Vault you might need additional configuration like -{docs}#vault.config.ssl[SSL] and -{docs}#vault.config.authentication[authentication]. - -If the application imports the `spring-boot-starter-actuator` project, the status of the vault server will be available via the `/health` endpoint. - -The vault health indicator can be enabled or disabled through the property `management.health.vault.enabled` (default to `true`). - -NOTE: With Spring Cloud Vault 3.0 and Spring Boot 2.4, the bootstrap context initialization (`bootstrap.yml`, `bootstrap.properties`) of property sources was deprecated. -Instead, Spring Cloud Vault favors Spring Boot's Config Data API which allows importing configuration from Vault. With Spring Boot Config Data approach, you need to set the `spring.config.import` property in order to bind to Vault. You can read more about it in the xref:config-data.adoc#vault.configdata.locations[Config Data Locations section]. -You can enable the bootstrap context either by setting the configuration property `spring.cloud.bootstrap.enabled=true` or by including the dependency `org.springframework.cloud:spring-cloud-starter-bootstrap`. - -[[authentication]] -== Authentication - -Vault requires an https://www.vaultproject.io/docs/concepts/auth.html[authentication mechanism] to https://www.vaultproject.io/docs/concepts/tokens.html[authorize client requests]. - -Spring Cloud Vault supports multiple {docs}#vault.config.authentication[authentication mechanisms] to authenticate applications with Vault. - -For a quickstart, use the root token printed by the xref:quickstart.adoc#quickstart.vault.start[Vault initialization]. - -.application.yml -==== -[source,yaml] ----- -spring.cloud.vault: - token: 19aefa97-cccc-bbbb-aaaa-225940e63d76 -spring.config.import: vault:// ----- -==== - -WARNING: Consider carefully your security requirements. -Static token authentication is fine if you want quickly get started with Vault, but a static token is not protected any further. -Any disclosure to unintended parties allows Vault use with the associated token roles. - - - diff --git a/docs/modules/ROOT/pages/secret-backends.adoc b/docs/modules/ROOT/pages/secret-backends.adoc deleted file mode 100644 index e83ae86d..00000000 --- a/docs/modules/ROOT/pages/secret-backends.adoc +++ /dev/null @@ -1,632 +0,0 @@ -[[vault.config.backends]] -= Secret Backends - -[[vault.config.backends.kv]] -[[vault.config.backends.generic]] -[[vault.config.backends.kv.versioned]] -== Key-Value Backend - -Spring Cloud Vault supports both Key-Value secret backends, the versioned (v2) and unversioned (v1). -The key-value backend allows storage of arbitrary values as key-value store. -A single context can store one or many key-value tuples. -Contexts can be organized hierarchically. -Spring Cloud Vault determines itself whether a secret is using versioning and maps the path to its appropriate URL. -Spring Cloud Vault allows using the Application name, and a default context name (`application`) in combination with active profiles. - ----- -/secret/{application}/{profile} -/secret/{application} -/secret/{default-context}/{profile} -/secret/{default-context} ----- - -The application name is determined by the properties: - -* `spring.cloud.vault.kv.application-name` -* `spring.cloud.vault.application-name` -* `spring.application.name` - -The profiles are determined by the properties: - -* `spring.cloud.vault.kv.profiles` -* `spring.profiles.active` - -Secrets can be obtained from other contexts within the key-value backend by adding their paths to the application name, separated by commas. -For example, given the application name `usefulapp,mysql1,projectx/aws`, each of these folders will be used: - -* `/secret/usefulapp` -* `/secret/mysql1` -* `/secret/projectx/aws` - -Spring Cloud Vault adds all active profiles to the list of possible context paths. -No active profiles will skip accessing contexts with a profile name. - -Properties are exposed like they are stored (i.e. without additional prefixes). - -NOTE: Spring Cloud Vault adds the `data/` context between the mount path and the actual context path depending on whether the mount uses the versioned key-value backend. - -==== -[source,yaml] ----- -spring.cloud.vault: - kv: - enabled: true - backend: secret - profile-separator: '/' - default-context: application - application-name: my-app - profiles: local, cloud ----- -==== - -* `enabled` setting this value to `false` disables the secret backend config usage -* `backend` sets the path of the secret mount to use -* `default-context` sets the context name used by all applications -* `application-name` overrides the application name for use in the key-value backend -* `profiles` overrides the active profiles for use in the key-value backend -* `profile-separator` separates the profile name from the context in property sources with profiles - -NOTE: The key-value secret backend can be operated in versioned (v2) and non-versioned (v1) modes. - -See also: - -* https://www.vaultproject.io/docs/secrets/kv/kv-v1.html[Vault Documentation: Using the KV Secrets Engine - Version 1 (generic secret backend)] -* https://www.vaultproject.io/docs/secrets/kv/kv-v2.html[Vault Documentation: Using the KV Secrets Engine - Version 2 (versioned key-value backend)] - -[[vault.config.backends.consul]] -== Consul - -Spring Cloud Vault can obtain credentials for HashiCorp Consul. -The Consul integration requires the `spring-cloud-vault-config-consul` -dependency. - -.pom.xml -==== -[source,xml,indent=0,subs="verbatim,quotes,attributes"] ----- - - - org.springframework.cloud - spring-cloud-vault-config-consul - {project-version} - - ----- -==== - -The integration can be enabled by setting -`spring.cloud.vault.consul.enabled=true` (default `false`) and providing the role name with `spring.cloud.vault.consul.role=…`. - -The obtained token is stored in `spring.cloud.consul.token` -so using Spring Cloud Consul can pick up the generated credentials without further configuration. -You can configure the property name by setting `spring.cloud.vault.consul.token-property`. - -==== -[source,yaml] ----- -spring.cloud.vault: - consul: - enabled: true - role: readonly - backend: consul - token-property: spring.cloud.consul.token ----- -==== - -* `enabled` setting this value to `true` enables the Consul backend config usage -* `role` sets the role name of the Consul role definition -* `backend` sets the path of the Consul mount to use -* `token-property` sets the property name in which the Consul ACL token is stored - -See also: https://www.vaultproject.io/docs/secrets/consul/index.html[Vault Documentation: Setting up Consul with Vault] - -[[vault.config.backends.rabbitmq]] -== RabbitMQ - -Spring Cloud Vault can obtain credentials for RabbitMQ. - -The RabbitMQ integration requires the `spring-cloud-vault-config-rabbitmq` -dependency. - -.pom.xml -==== -[source,xml,indent=0,subs="verbatim,quotes,attributes"] ----- - - - org.springframework.cloud - spring-cloud-vault-config-rabbitmq - {project-version} - - ----- -==== - -The integration can be enabled by setting -`spring.cloud.vault.rabbitmq.enabled=true` (default `false`) and providing the role name with `spring.cloud.vault.rabbitmq.role=…`. - -Username and password are stored in `spring.rabbitmq.username` -and `spring.rabbitmq.password` so using Spring Boot will pick up the generated credentials without further configuration. -You can configure the property names by setting `spring.cloud.vault.rabbitmq.username-property` and -`spring.cloud.vault.rabbitmq.password-property`. - -==== -[source,yaml] ----- -spring.cloud.vault: - rabbitmq: - enabled: true - role: readonly - backend: rabbitmq - username-property: spring.rabbitmq.username - password-property: spring.rabbitmq.password ----- -==== - -* `enabled` setting this value to `true` enables the RabbitMQ backend config usage -* `role` sets the role name of the RabbitMQ role definition -* `backend` sets the path of the RabbitMQ mount to use -* `username-property` sets the property name in which the RabbitMQ username is stored -* `password-property` sets the property name in which the RabbitMQ password is stored - -See also: https://www.vaultproject.io/docs/secrets/rabbitmq/index.html[Vault Documentation: Setting up RabbitMQ with Vault] - -[[vault.config.backends.aws]] -== AWS - -Spring Cloud Vault can obtain credentials for AWS. - -The AWS integration requires the `spring-cloud-vault-config-aws` -dependency. - -.pom.xml -==== -[source,xml,indent=0,subs="verbatim,quotes,attributes"] ----- - - - org.springframework.cloud - spring-cloud-vault-config-aws - {project-version} - - ----- -==== - -The integration can be enabled by setting -`spring.cloud.vault.aws=true` (default `false`) and providing the role name with `spring.cloud.vault.aws.role=…`. - -Supported AWS credential Types: - -* iam_user (Defaults) -* assumed_role (STS) -* federation_token (STS) - -The access key and secret key are stored in `cloud.aws.credentials.accessKey` -and `cloud.aws.credentials.secretKey`. So using Spring Cloud AWS will pick up the generated credentials without further configuration. - -You can configure the property names by setting `spring.cloud.vault.aws.access-key-property` and -`spring.cloud.vault.aws.secret-key-property`. - -For STS security token, you can configure the property name by setting `spring.cloud.vault.aws.session-token-key-property`. The security token is stored under `cloud.aws.credentials.sessionToken` (defaults). - -Example: iam_user - -==== -[source,yaml] ----- -spring.cloud.vault: - aws: - enabled: true - role: readonly - backend: aws - access-key-property: cloud.aws.credentials.accessKey - secret-key-property: cloud.aws.credentials.secretKey ----- -==== - -Example: assumed_role (STS) -==== -[source,yaml] ----- -spring.cloud.vault: - aws: - enabled: true - role: sts-vault-role - backend: aws - credential-type: assumed_role - access-key-property: cloud.aws.credentials.accessKey - secret-key-property: cloud.aws.credentials.secretKey - session-token-key-property: cloud.aws.credentials.sessionToken - ttl: 3600s - role-arn: arn:aws:iam::${AWS_ACCOUNT}:role/sts-app-role ----- -==== - -* `enabled` setting this value to `true` enables the AWS backend config usage -* `role` sets the role name of the AWS role definition -* `backend` sets the path of the AWS mount to use -* `access-key-property` sets the property name in which the AWS access key is stored -* `secret-key-property` sets the property name in which the AWS secret key is stored -* `session-token-key-property` sets the property name in which the AWS STS security token is stored. -* `credential-type` sets the aws credential type to use for this backend. Defaults to `iam_user` -* `ttl` sets the ttl for the STS token when using `assumed_role` or `federation_token`. Defaults to the ttl specified by the vault role. Min/Max values are also limited to what AWS would support for STS. -* `role-arn` sets the IAM role to assume if more than one are configured for the vault role when using `assumed_role`. - -See also: https://www.vaultproject.io/docs/secrets/aws/index.html[Vault Documentation: Setting up AWS with Vault] - -[[vault.config.backends.database-backends]] -= Database backends - -Vault supports several database secret backends to generate database credentials dynamically based on configured roles. -This means services that need to access a database no longer need to configure credentials: they can request them from Vault, and use Vault's leasing mechanism to more easily roll keys. - -Spring Cloud Vault integrates with these backends: - -* xref:secret-backends.adoc#vault.config.backends.database[Database] -* xref:secret-backends.adoc#vault.config.backends.cassandra[Apache Cassandra] -* xref:secret-backends.adoc#vault.config.backends.couchbase[Couchbase Database] -* xref:secret-backends.adoc#vault.config.backends.elasticsearch[Elasticsearch] -* xref:secret-backends.adoc#vault.config.backends.mongodb[MongoDB] -* xref:secret-backends.adoc#vault.config.backends.mysql[MySQL] -* xref:secret-backends.adoc#vault.config.backends.postgresql[PostgreSQL] - -Using a database secret backend requires to enable the backend in the configuration and the `spring-cloud-vault-config-databases` -dependency. - -Vault ships since 0.7.1 with a dedicated `database` secret backend that allows database integration via plugins. -You can use that specific backend by using the generic database backend. -Make sure to specify the appropriate backend path, e.g. `spring.cloud.vault.mysql.role.backend=database`. - -.pom.xml -==== -[source,xml,indent=0,subs="verbatim,quotes,attributes"] ----- - - - org.springframework.cloud - spring-cloud-vault-config-databases - {project-version} - - ----- -==== - -NOTE: Enabling multiple JDBC-compliant databases will generate credentials and store them by default in the same property keys hence property names for JDBC secrets need to be configured separately. - -[[vault.config.backends.database]] -== Database - -Spring Cloud Vault can obtain credentials for any database listed at -https://www.vaultproject.io/api/secret/databases/index.html. -The integration can be enabled by setting -`spring.cloud.vault.database.enabled=true` (default `false`) and providing the role name with `spring.cloud.vault.database.role=…`. - -While the database backend is a generic one, `spring.cloud.vault.database` -specifically targets JDBC databases. -Username and password are available from `spring.datasource.username` and `spring.datasource.password` properties -so using Spring Boot will pick up the generated credentials for your `DataSource` without further configuration. -You can configure the property names by setting -`spring.cloud.vault.database.username-property` and -`spring.cloud.vault.database.password-property`. - -==== -[source,yaml] ----- -spring.cloud.vault: - database: - enabled: true - role: readonly - backend: database - username-property: spring.datasource.username - password-property: spring.datasource.password ----- -==== - -[[vault.config.backends.databases]] -== Multiple Databases - -Sometimes, credentials for a single database isn't sufficient because an application might connect to two or more databases of the same kind. -Beginning with version 3.0.5, Spring Vault supports the configuration of multiple database secret backends under the `spring.cloud.vault.databases.*` namespace. - -The configuration accepts multiple database backends to materialize credentials into the specified properties. Make sure to configure `username-property` and `password-property` appropriately. - -==== -[source,yaml] ----- -spring.cloud.vault: - databases: - primary: - enabled: true - role: readwrite - backend: database - username-property: spring.primary-datasource.username - password-property: spring.primary-datasource.password - other-database: - enabled: true - role: readonly - backend: database - username-property: spring.secondary-datasource.username - password-property: spring.secondary-datasource.password ----- -==== - -* `` descriptive name of the database configuration. -* `.enabled` setting this value to `true` enables the Database backend config usage -* `.role` sets the role name of the Database role definition -* `.backend` sets the path of the Database mount to use -* `.username-property` sets the property name in which the Database username is stored. Make sure to use unique property names to avoid property shadowing. -* `.password-property` sets the property name in which the Database password is stored Make sure to use unique property names to avoid property shadowing. - -See also: https://www.vaultproject.io/docs/secrets/databases/index.html[Vault Documentation: Database Secrets backend] - -WARNING: Spring Cloud Vault does not support getting new credentials and configuring your `DataSource` with them when the maximum lease time has been reached. -That is, if `max_ttl` of the Database role in Vault is set to `24h` that means that 24 hours after your application has started it can no longer authenticate with the database. - -[[vault.config.backends.cassandra]] -== Apache Cassandra - -NOTE: The `cassandra` backend has been deprecated in Vault 0.7.1 and it is recommended to use the `database` backend and mount it as `cassandra`. - -Spring Cloud Vault can obtain credentials for Apache Cassandra. -The integration can be enabled by setting -`spring.cloud.vault.cassandra.enabled=true` (default `false`) and providing the role name with `spring.cloud.vault.cassandra.role=…`. - -Username and password are available from `spring.data.cassandra.username` -and `spring.data.cassandra.password` properties so using Spring Boot will pick up the generated credentials without further configuration. -You can configure the property names by setting -`spring.cloud.vault.cassandra.username-property` and -`spring.cloud.vault.cassandra.password-property`. - -==== -[source,yaml] ----- -spring.cloud.vault: - cassandra: - enabled: true - role: readonly - backend: cassandra - username-property: spring.data.cassandra.username - password-property: spring.data.cassandra.password ----- -==== - -* `enabled` setting this value to `true` enables the Cassandra backend config usage -* `role` sets the role name of the Cassandra role definition -* `backend` sets the path of the Cassandra mount to use -* `username-property` sets the property name in which the Cassandra username is stored -* `password-property` sets the property name in which the Cassandra password is stored - -See also: https://www.vaultproject.io/docs/secrets/cassandra/index.html[Vault Documentation: Setting up Apache Cassandra with Vault] - -[[vault.config.backends.couchbase]] -== Couchbase Database - -Spring Cloud Vault can obtain credentials for Couchbase. -The integration can be enabled by setting -`spring.cloud.vault.couchbase.enabled=true` (default `false`) and providing the role name with `spring.cloud.vault.couchbase.role=…`. - -Username and password are available from `spring.couchbase.username` -and `spring.couchbase.password` properties so using Spring Boot will pick up the generated credentials without further configuration. -You can configure the property names by setting -`spring.cloud.vault.couchbase.username-property` and -`spring.cloud.vault.couchbase.password-property`. - -==== -[source,yaml] ----- -spring.cloud.vault: - couchbase: - enabled: true - role: readonly - backend: database - username-property: spring.couchbase.username - password-property: spring.couchbase.password ----- -==== - -* `enabled` setting this value to `true` enables the Couchbase backend config usage -* `role` sets the role name of the Couchbase role definition -* `backend` sets the path of the Couchbase mount to use -* `username-property` sets the property name in which the Couchbase username is stored -* `password-property` sets the property name in which the Couchbase password is stored - -See also: https://github.com/hashicorp/vault-plugin-database-couchbase[Couchbase Database Plugin Documentation] - -[[vault.config.backends.elasticsearch]] -== Elasticsearch - -Spring Cloud Vault can obtain since version 3.0 credentials for Elasticsearch. -The integration can be enabled by setting -`spring.cloud.vault.elasticsearch.enabled=true` (default `false`) and providing the role name with `spring.cloud.vault.elasticsearch.role=…`. - -Username and password are available from `spring.elasticsearch.rest.username` -and `spring.elasticsearch.rest.password` properties so using Spring Boot will pick up the generated credentials without further configuration. -You can configure the property names by setting -`spring.cloud.vault.elasticsearch.username-property` and -`spring.cloud.vault.elasticsearch.password-property`. - -==== -[source,yaml] ----- -spring.cloud.vault: - elasticsearch: - enabled: true - role: readonly - backend: mongodb - username-property: spring.elasticsearch.rest.username - password-property: spring.elasticsearch.rest.password ----- -==== - -* `enabled` setting this value to `true` enables the Elasticsearch database backend config usage -* `role` sets the role name of the Elasticsearch role definition -* `backend` sets the path of the Elasticsearch mount to use -* `username-property` sets the property name in which the Elasticsearch username is stored -* `password-property` sets the property name in which the Elasticsearch password is stored - -See also: https://www.vaultproject.io/docs/secrets/databases/elasticdb[Vault Documentation: Setting up Elasticsearch with Vault] - -[[vault.config.backends.mongodb]] -== MongoDB - -NOTE: The `mongodb` backend has been deprecated in Vault 0.7.1 and it is recommended to use the `database` backend and mount it as `mongodb`. - -Spring Cloud Vault can obtain credentials for MongoDB. -The integration can be enabled by setting -`spring.cloud.vault.mongodb.enabled=true` (default `false`) and providing the role name with `spring.cloud.vault.mongodb.role=…`. - -Username and password are stored in `spring.data.mongodb.username` -and `spring.data.mongodb.password` so using Spring Boot will pick up the generated credentials without further configuration. -You can configure the property names by setting -`spring.cloud.vault.mongodb.username-property` and -`spring.cloud.vault.mongodb.password-property`. - -==== -[source,yaml] ----- -spring.cloud.vault: - mongodb: - enabled: true - role: readonly - backend: mongodb - username-property: spring.data.mongodb.username - password-property: spring.data.mongodb.password ----- -==== - -* `enabled` setting this value to `true` enables the MongodB backend config usage -* `role` sets the role name of the MongoDB role definition -* `backend` sets the path of the MongoDB mount to use -* `username-property` sets the property name in which the MongoDB username is stored -* `password-property` sets the property name in which the MongoDB password is stored - -See also: https://www.vaultproject.io/docs/secrets/mongodb/index.html[Vault Documentation: Setting up MongoDB with Vault] - -[[vault.config.backends.mysql]] -== MySQL - -NOTE: The `mysql` backend has been deprecated in Vault 0.7.1 and it is recommended to use the `database` backend and mount it as `mysql`. -Configuration for `spring.cloud.vault.mysql` will be removed in a future version. - -Spring Cloud Vault can obtain credentials for MySQL. -The integration can be enabled by setting -`spring.cloud.vault.mysql.enabled=true` (default `false`) and providing the role name with `spring.cloud.vault.mysql.role=…`. - -Username and password are available from `spring.datasource.username` -and `spring.datasource.password` properties so using Spring Boot will pick up the generated credentials without further configuration. -You can configure the property names by setting -`spring.cloud.vault.mysql.username-property` and -`spring.cloud.vault.mysql.password-property`. - -==== -[source,yaml] ----- -spring.cloud.vault: - mysql: - enabled: true - role: readonly - backend: mysql - username-property: spring.datasource.username - password-property: spring.datasource.password ----- -==== - -* `enabled` setting this value to `true` enables the MySQL backend config usage -* `role` sets the role name of the MySQL role definition -* `backend` sets the path of the MySQL mount to use -* `username-property` sets the property name in which the MySQL username is stored -* `password-property` sets the property name in which the MySQL password is stored - -See also: https://www.vaultproject.io/docs/secrets/mysql/index.html[Vault Documentation: Setting up MySQL with Vault] - -[[vault.config.backends.postgresql]] -== PostgreSQL - -NOTE: The `postgresql` backend has been deprecated in Vault 0.7.1 and it is recommended to use the `database` backend and mount it as `postgresql`. -Configuration for `spring.cloud.vault.postgresql` will be removed in a future version. - -Spring Cloud Vault can obtain credentials for PostgreSQL. -The integration can be enabled by setting -`spring.cloud.vault.postgresql.enabled=true` (default `false`) and providing the role name with `spring.cloud.vault.postgresql.role=…`. - -Username and password are available from `spring.datasource.username` -and `spring.datasource.password` properties so using Spring Boot will pick up the generated credentials without further configuration. -You can configure the property names by setting -`spring.cloud.vault.postgresql.username-property` and -`spring.cloud.vault.postgresql.password-property`. - -==== -[source,yaml] ----- -spring.cloud.vault: - postgresql: - enabled: true - role: readonly - backend: postgresql - username-property: spring.datasource.username - password-property: spring.datasource.password ----- -==== - -* `enabled` setting this value to `true` enables the PostgreSQL backend config usage -* `role` sets the role name of the PostgreSQL role definition -* `backend` sets the path of the PostgreSQL mount to use -* `username-property` sets the property name in which the PostgreSQL username is stored -* `password-property` sets the property name in which the PostgreSQL password is stored - -See also: https://www.vaultproject.io/docs/secrets/postgresql/index.html[Vault Documentation: Setting up PostgreSQL with Vault] - -[[vault.config.backends.configurer]] -= Customize which secret backends to expose as PropertySource - -Spring Cloud Vault uses property-based configuration to create ``PropertySource``s for key-value and discovered secret backends. - -Discovered backends provide `VaultSecretBackendDescriptor` beans to describe the configuration state to use secret backend as `PropertySource`. -A `SecretBackendMetadataFactory` is required to create a `SecretBackendMetadata` object which contains path, name and property transformation configuration. - -`SecretBackendMetadata` is used to back a particular `PropertySource`. - -You can register a `VaultConfigurer` for customization. -Default key-value and discovered backend registration is disabled if you provide a `VaultConfigurer`. -You can however enable default registration with -`SecretBackendConfigurer.registerDefaultKeyValueSecretBackends()` and `SecretBackendConfigurer.registerDefaultDiscoveredSecretBackends()`. - -==== -[source,java] ----- -public class CustomizationBean implements VaultConfigurer { - - @Override - public void addSecretBackends(SecretBackendConfigurer configurer) { - - configurer.add("secret/my-application"); - - configurer.registerDefaultKeyValueSecretBackends(false); - configurer.registerDefaultDiscoveredSecretBackends(true); - } -} ----- -[source,java] ----- -SpringApplication application = new SpringApplication(MyApplication.class); -application.addBootstrapper(VaultBootstrapper.fromConfigurer(new CustomizationBean())); ----- -==== - -[[vault.config.backends.custom]] -= Custom Secret Backend Implementations - -Spring Cloud Vault ships with secret backend support for the most common backend integrations. -You can integrate with any kind of backend by providing an implementation that describes how to obtain data from the backend you want to use and how to surface data provided by that backend by providing a `PropertyTransformer`. - -Adding a custom implementation for a backend requires implementation of two interfaces: - -* `org.springframework.cloud.vault.config.VaultSecretBackendDescriptor` -* `org.springframework.cloud.vault.config.SecretBackendMetadataFactory` - -`VaultSecretBackendDescriptor` is typically an object that holds configuration data, such as `VaultDatabaseProperties`. Spring Cloud Vault requires that your type is annotated with `@ConfigurationProperties` to materialize the class from the configuration. - -`SecretBackendMetadataFactory` accepts `VaultSecretBackendDescriptor` to create the actual `SecretBackendMetadata` object which holds the context path within your Vault server, any path variables required to resolve parametrized context paths and `PropertyTransformer`. - -Both, `VaultSecretBackendDescriptor` and `SecretBackendMetadataFactory` types must be registered in `spring.factories` which is an extension mechanism provided by Spring, similar to Java's ServiceLoader. diff --git a/docs/modules/ROOT/pages/spring-cloud-vault.adoc b/docs/modules/ROOT/pages/spring-cloud-vault.adoc deleted file mode 100644 index a44d3bf1..00000000 --- a/docs/modules/ROOT/pages/spring-cloud-vault.adoc +++ /dev/null @@ -1,25 +0,0 @@ -[[spring-cloud-vault]] -= Spring Cloud Vault -:page-section-summary-toc: 1 -:page-section-summary-toc: 1 -:github: https://github.com/spring-cloud/spring-cloud-vault -:githubmaster: {github}/tree/master -:revnumber: {project-version} -:docslink: {githubmaster}/docs/src/main/asciidoc -:nofooter: - -(C) 2016-2021 the original authors. - -NOTE: _Copies of this document may be made for your own use and for distribution to others, provided that you do not charge any fee for such copies and further provided that each copy contains this Copyright Notice, whether distributed in print or electronically._ - - - - -[[quick-start]] -== Quick Start - - - - - - diff --git a/docs/pom.xml b/docs/pom.xml deleted file mode 100644 index a0ea35a7..00000000 --- a/docs/pom.xml +++ /dev/null @@ -1,132 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-vault-parent - 4.1.0-SNAPSHOT - .. - - - spring-cloud-vault-docs - 4.1.0-SNAPSHOT - - jar - Spring Cloud Vault Docs - Spring Cloud Docs - - - spring-cloud-vault - ${basedir}/.. - spring.cloud.vault.*| - - deploy - - - - - ${project.groupId} - spring-cloud-starter-vault-config - - - ${project.groupId} - spring-cloud-vault-config-aws - - - ${project.groupId} - spring-cloud-vault-config-consul - - - ${project.groupId} - spring-cloud-vault-config-databases - - - ${project.groupId} - spring-cloud-vault-config-rabbitmq - - - - - src/main/asciidoc - - - - org.apache.maven.plugins - maven-jar-plugin - 3.2.0 - - - org.apache.maven.plugins - maven-source-plugin - 3.2.1 - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.2.0 - - - org.apache.maven.plugins - maven-deploy-plugin - 2.8.2 - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - - - - - - - docs - - - - pl.project13.maven - git-commit-id-plugin - - - org.apache.maven.plugins - maven-dependency-plugin - - - org.apache.maven.plugins - maven-resources-plugin - - - org.codehaus.mojo - exec-maven-plugin - - - org.asciidoctor - asciidoctor-maven-plugin - - - org.apache.maven.plugins - maven-antrun-plugin - - - maven-deploy-plugin - - - - - - - - - spring-milestones - Spring Milestones - https://repo.spring.io/milestone - - false - - - - diff --git a/docs/src/main/asciidoc/ghpages.sh b/docs/src/main/asciidoc/ghpages.sh deleted file mode 100755 index 55e76be1..00000000 --- a/docs/src/main/asciidoc/ghpages.sh +++ /dev/null @@ -1,330 +0,0 @@ -#!/bin/bash -x - -set -e - -# Set default props like MAVEN_PATH, ROOT_FOLDER etc. -function set_default_props() { - # The script should be executed from the root folder - ROOT_FOLDER=`pwd` - echo "Current folder is ${ROOT_FOLDER}" - - if [[ ! -e "${ROOT_FOLDER}/.git" ]]; then - echo "You're not in the root folder of the project!" - exit 1 - fi - - # Prop that will let commit the changes - COMMIT_CHANGES="no" - MAVEN_PATH=${MAVEN_PATH:-} - echo "Path to Maven is [${MAVEN_PATH}]" - REPO_NAME=${PWD##*/} - echo "Repo name is [${REPO_NAME}]" - SPRING_CLOUD_STATIC_REPO=${SPRING_CLOUD_STATIC_REPO:-git@github.com:spring-cloud/spring-cloud-static.git} - echo "Spring Cloud Static repo is [${SPRING_CLOUD_STATIC_REPO}" -} - -# Check if gh-pages exists and docs have been built -function check_if_anything_to_sync() { - git remote set-url --push origin `git config remote.origin.url | sed -e 's/^git:/https:/'` - - if ! (git remote set-branches --add origin gh-pages && git fetch -q); then - echo "No gh-pages, so not syncing" - exit 0 - fi - - if ! [ -d docs/target/generated-docs ] && ! [ "${BUILD}" == "yes" ]; then - echo "No gh-pages sources in docs/target/generated-docs, so not syncing" - exit 0 - fi -} - -function retrieve_current_branch() { - # Code getting the name of the current branch. For master we want to publish as we did until now - # https://stackoverflow.com/questions/1593051/how-to-programmatically-determine-the-current-checked-out-git-branch - # If there is a branch already passed will reuse it - otherwise will try to find it - CURRENT_BRANCH=${BRANCH} - if [[ -z "${CURRENT_BRANCH}" ]] ; then - CURRENT_BRANCH=$(git symbolic-ref -q HEAD) - CURRENT_BRANCH=${CURRENT_BRANCH##refs/heads/} - CURRENT_BRANCH=${CURRENT_BRANCH:-HEAD} - fi - echo "Current branch is [${CURRENT_BRANCH}]" - git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script" -} - -# Switches to the provided value of the release version. We always prefix it with `v` -function switch_to_tag() { - git checkout v${VERSION} -} - -# Build the docs if switch is on -function build_docs_if_applicable() { - if [[ "${BUILD}" == "yes" ]] ; then - ./mvnw clean install -P docs -pl docs -DskipTests - fi -} - -# Get the name of the `docs.main` property -# Get whitelisted branches - assumes that a `docs` module is available under `docs` profile -function retrieve_doc_properties() { - MAIN_ADOC_VALUE=$("${MAVEN_PATH}"mvn -q \ - -Dexec.executable="echo" \ - -Dexec.args='${docs.main}' \ - --non-recursive \ - org.codehaus.mojo:exec-maven-plugin:1.3.1:exec) - echo "Extracted 'main.adoc' from Maven build [${MAIN_ADOC_VALUE}]" - - - WHITELIST_PROPERTY=${WHITELIST_PROPERTY:-"docs.whitelisted.branches"} - WHITELISTED_BRANCHES_VALUE=$("${MAVEN_PATH}"mvn -q \ - -Dexec.executable="echo" \ - -Dexec.args="\${${WHITELIST_PROPERTY}}" \ - org.codehaus.mojo:exec-maven-plugin:1.3.1:exec \ - -P docs \ - -pl docs) - echo "Extracted '${WHITELIST_PROPERTY}' from Maven build [${WHITELISTED_BRANCHES_VALUE}]" -} - -# Stash any outstanding changes -function stash_changes() { - git diff-index --quiet HEAD && dirty=$? || (echo "Failed to check if the current repo is dirty. Assuming that it is." && dirty="1") - if [ "$dirty" != "0" ]; then git stash; fi -} - -# Switch to gh-pages branch to sync it with current branch -function add_docs_from_target() { - local DESTINATION_REPO_FOLDER - if [[ -z "${DESTINATION}" && -z "${CLONE}" ]] ; then - DESTINATION_REPO_FOLDER=${ROOT_FOLDER} - elif [[ "${CLONE}" == "yes" ]]; then - mkdir -p ${ROOT_FOLDER}/target - local clonedStatic=${ROOT_FOLDER}/target/spring-cloud-static - if [[ ! -e "${clonedStatic}/.git" ]]; then - echo "Cloning Spring Cloud Static to target" - git clone ${SPRING_CLOUD_STATIC_REPO} ${clonedStatic} && git checkout gh-pages - else - echo "Spring Cloud Static already cloned - will pull changes" - cd ${clonedStatic} && git checkout gh-pages && git pull origin gh-pages - fi - DESTINATION_REPO_FOLDER=${clonedStatic}/${REPO_NAME} - mkdir -p ${DESTINATION_REPO_FOLDER} - else - if [[ ! -e "${DESTINATION}/.git" ]]; then - echo "[${DESTINATION}] is not a git repository" - exit 1 - fi - DESTINATION_REPO_FOLDER=${DESTINATION}/${REPO_NAME} - mkdir -p ${DESTINATION_REPO_FOLDER} - echo "Destination was provided [${DESTINATION}]" - fi - cd ${DESTINATION_REPO_FOLDER} - git checkout gh-pages - git pull origin gh-pages - - # Add git branches - ################################################################### - if [[ -z "${VERSION}" ]] ; then - copy_docs_for_current_version - else - copy_docs_for_provided_version - fi - commit_changes_if_applicable -} - - -# Copies the docs by using the retrieved properties from Maven build -function copy_docs_for_current_version() { - if [[ "${CURRENT_BRANCH}" == "master" ]] ; then - echo -e "Current branch is master - will copy the current docs only to the root folder" - for f in docs/target/generated-docs/*; do - file=${f#docs/target/generated-docs/*} - if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then - # Not ignored... - cp -rf $f ${ROOT_FOLDER}/ - git add -A ${ROOT_FOLDER}/$file - fi - done - COMMIT_CHANGES="yes" - else - echo -e "Current branch is [${CURRENT_BRANCH}]" - # https://stackoverflow.com/questions/29300806/a-bash-script-to-check-if-a-string-is-present-in-a-comma-separated-list-of-strin - if [[ ",${WHITELISTED_BRANCHES_VALUE}," = *",${CURRENT_BRANCH},"* ]] ; then - mkdir -p ${ROOT_FOLDER}/${CURRENT_BRANCH} - echo -e "Branch [${CURRENT_BRANCH}] is whitelisted! Will copy the current docs to the [${CURRENT_BRANCH}] folder" - for f in docs/target/generated-docs/*; do - file=${f#docs/target/generated-docs/*} - if ! git ls-files -i -o --exclude-standard --directory | grep -q ^$file$; then - # Not ignored... - # We want users to access 1.0.0.RELEASE/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html - if [[ "${file}" == "${MAIN_ADOC_VALUE}.html" ]] ; then - # We don't want to copy the spring-cloud-sleuth.html - # we want it to be converted to index.html - cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html - git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/index.html - else - cp -rf $f ${ROOT_FOLDER}/${CURRENT_BRANCH} - git add -A ${ROOT_FOLDER}/${CURRENT_BRANCH}/$file - fi - fi - done - COMMIT_CHANGES="yes" - else - echo -e "Branch [${CURRENT_BRANCH}] is not on the white list! Check out the Maven [${WHITELIST_PROPERTY}] property in - [docs] module available under [docs] profile. Won't commit any changes to gh-pages for this branch." - fi - fi -} - -# Copies the docs by using the explicitly provided version -function copy_docs_for_provided_version() { - local FOLDER=${DESTINATION_REPO_FOLDER}/${VERSION} - mkdir -p ${FOLDER} - echo -e "Current tag is [v${VERSION}] Will copy the current docs to the [${FOLDER}] folder" - for f in ${ROOT_FOLDER}/docs/target/generated-docs/*; do - file=${f#${ROOT_FOLDER}/docs/target/generated-docs/*} - copy_docs_for_branch ${file} ${FOLDER} - done - COMMIT_CHANGES="yes" - CURRENT_BRANCH="v${VERSION}" -} - -# Copies the docs from target to the provided destination -# Params: -# $1 - file from target -# $2 - destination to which copy the files -function copy_docs_for_branch() { - local file=$1 - local destination=$2 - if ! git ls-files -i -o --exclude-standard --directory | grep -q ^${file}$; then - # Not ignored... - # We want users to access 1.0.0.RELEASE/ instead of 1.0.0.RELEASE/spring-cloud.sleuth.html - if [[ ("${file}" == "${MAIN_ADOC_VALUE}.html") || ("${file}" == "${REPO_NAME}.html") ]] ; then - # We don't want to copy the spring-cloud-sleuth.html - # we want it to be converted to index.html - cp -rf $f ${destination}/index.html - git add -A ${destination}/index.html - else - cp -rf $f ${destination} - git add -A ${destination}/$file - fi - fi -} - -function commit_changes_if_applicable() { - if [[ "${COMMIT_CHANGES}" == "yes" ]] ; then - COMMIT_SUCCESSFUL="no" - git commit -a -m "Sync docs from ${CURRENT_BRANCH} to gh-pages" && COMMIT_SUCCESSFUL="yes" || echo "Failed to commit changes" - - # Uncomment the following push if you want to auto push to - # the gh-pages branch whenever you commit to master locally. - # This is a little extreme. Use with care! - ################################################################### - if [[ "${COMMIT_SUCCESSFUL}" == "yes" ]] ; then - git push origin gh-pages - fi - fi -} - -# Switch back to the previous branch and exit block -function checkout_previous_branch() { - # If -version was provided we need to come back to root project - cd ${ROOT_FOLDER} - git checkout ${CURRENT_BRANCH} || echo "Failed to check the branch... continuing with the script" - if [ "$dirty" != "0" ]; then git stash pop; fi - exit 0 -} - -# Assert if properties have been properly passed -function assert_properties() { -echo "VERSION [${VERSION}], DESTINATION [${DESTINATION}], CLONE [${CLONE}]" -if [[ "${VERSION}" != "" && (-z "${DESTINATION}" && -z "${CLONE}") ]] ; then echo "Version was set but destination / clone was not!"; exit 1;fi -if [[ ("${DESTINATION}" != "" && "${CLONE}" != "") && -z "${VERSION}" ]] ; then echo "Destination / clone was set but version was not!"; exit 1;fi -if [[ "${DESTINATION}" != "" && "${CLONE}" == "yes" ]] ; then echo "Destination and clone was set. Pick one!"; exit 1;fi -} - -# Prints the usage -function print_usage() { -cat </` -- if the destination switch is passed (-d) then the script will check if the provided dir is a git repo and then will - switch to gh-pages of that repo and copy the generated docs to `docs//` - -USAGE: - -You can use the following options: - --v|--version - the script will apply the whole procedure for a particular library version --d|--destination - the root of destination folder where the docs should be copied. You have to use the full path. - E.g. point to spring-cloud-static folder. Can't be used with (-c) --b|--build - will run the standard build process after checking out the branch --c|--clone - will automatically clone the spring-cloud-static repo instead of providing the destination. - Obviously can't be used with (-d) - -EOF -} - - -# ========================================== -# ____ ____ _____ _____ _____ _______ -# / ____|/ ____| __ \|_ _| __ \__ __| -# | (___ | | | |__) | | | | |__) | | | -# \___ \| | | _ / | | | ___/ | | -# ____) | |____| | \ \ _| |_| | | | -# |_____/ \_____|_| \_\_____|_| |_| -# -# ========================================== - -while [[ $# > 0 ]] -do -key="$1" -case ${key} in - -v|--version) - VERSION="$2" - shift # past argument - ;; - -d|--destination) - DESTINATION="$2" - shift # past argument - ;; - -b|--build) - BUILD="yes" - ;; - -c|--clone) - CLONE="yes" - ;; - -h|--help) - print_usage - exit 0 - ;; - *) - echo "Invalid option: [$1]" - print_usage - exit 1 - ;; -esac -shift # past argument or value -done - -assert_properties -set_default_props -check_if_anything_to_sync -if [[ -z "${VERSION}" ]] ; then - retrieve_current_branch -else - switch_to_tag -fi -build_docs_if_applicable -retrieve_doc_properties -stash_changes -add_docs_from_target -checkout_previous_branch \ No newline at end of file diff --git a/download/vault_1.5.0_darwin_amd64.zip b/download/vault_1.5.0_darwin_amd64.zip new file mode 100644 index 00000000..150889c8 Binary files /dev/null and b/download/vault_1.5.0_darwin_amd64.zip differ diff --git a/etc/ide/eclipse-code-formatter.xml b/etc/ide/eclipse-code-formatter.xml deleted file mode 100644 index 24955522..00000000 --- a/etc/ide/eclipse-code-formatter.xml +++ /dev/null @@ -1,755 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/mvnw b/mvnw index 41f7bd60..41c0f0c2 100755 --- a/mvnw +++ b/mvnw @@ -8,7 +8,7 @@ # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # -# https://www.apache.org/licenses/LICENSE-2.0 +# http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an @@ -19,7 +19,7 @@ # ---------------------------------------------------------------------------- # ---------------------------------------------------------------------------- -# Maven2 Start Up Batch script +# Maven Start Up Batch script # # Required ENV vars: # ------------------ @@ -54,38 +54,16 @@ case "`uname`" in CYGWIN*) cygwin=true ;; MINGW*) mingw=true;; Darwin*) darwin=true - # - # Look for the Apple JDKs first to preserve the existing behaviour, and then look - # for the new JDKs provided by Oracle. - # - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Frameworks/JavaVM.framework/Versions/CurrentJDK/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L /System/Library/Java/JavaVirtualMachines/CurrentJDK ] ; then - # - # Apple JDKs - # - export JAVA_HOME=/System/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -L "/Library/Java/JavaVirtualMachines/CurrentJDK" ] ; then - # - # Oracle JDKs - # - export JAVA_HOME=/Library/Java/JavaVirtualMachines/CurrentJDK/Contents/Home - fi - - if [ -z "$JAVA_HOME" ] && [ -x "/usr/libexec/java_home" ]; then - # - # Apple JDKs - # - export JAVA_HOME=`/usr/libexec/java_home` - fi - ;; + # Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home + # See https://developer.apple.com/library/mac/qa/qa1170/_index.html + if [ -z "$JAVA_HOME" ]; then + if [ -x "/usr/libexec/java_home" ]; then + export JAVA_HOME="`/usr/libexec/java_home`" + else + export JAVA_HOME="/Library/Java/Home" + fi + fi + ;; esac if [ -z "$JAVA_HOME" ] ; then @@ -130,13 +108,12 @@ if $cygwin ; then CLASSPATH=`cygpath --path --unix "$CLASSPATH"` fi -# For Migwn, ensure paths are in UNIX format before anything is touched +# For Mingw, ensure paths are in UNIX format before anything is touched if $mingw ; then [ -n "$M2_HOME" ] && M2_HOME="`(cd "$M2_HOME"; pwd)`" [ -n "$JAVA_HOME" ] && JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`" - # TODO classpath? fi if [ -z "$JAVA_HOME" ]; then @@ -184,27 +161,28 @@ fi CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher -# For Cygwin, switch paths to Windows format before running java -if $cygwin; then - [ -n "$M2_HOME" ] && - M2_HOME=`cygpath --path --windows "$M2_HOME"` - [ -n "$JAVA_HOME" ] && - JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` - [ -n "$CLASSPATH" ] && - CLASSPATH=`cygpath --path --windows "$CLASSPATH"` -fi - # traverses directory structure from process work directory to filesystem root # first directory with .mvn subdirectory is considered project base directory find_maven_basedir() { - local basedir=$(pwd) - local wdir=$(pwd) + + if [ -z "$1" ] + then + echo "Path not specified to find_maven_basedir" + return 1 + fi + + basedir="$1" + wdir="$1" while [ "$wdir" != '/' ] ; do if [ -d "$wdir"/.mvn ] ; then basedir=$wdir break fi - wdir=$(cd "$wdir/.."; pwd) + # workaround for JBEAP-8937 (on Solaris 10/Sparc) + if [ -d "${wdir}" ]; then + wdir=`cd "$wdir/.."; pwd` + fi + # end of workaround done echo "${basedir}" } @@ -216,9 +194,108 @@ concat_lines() { fi } -export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-$(find_maven_basedir)} +BASE_DIR=`find_maven_basedir "$(pwd)"` +if [ -z "$BASE_DIR" ]; then + exit 1; +fi + +########################################################################################## +# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +# This allows using the maven wrapper in projects that prohibit checking in binary data. +########################################################################################## +if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found .mvn/wrapper/maven-wrapper.jar" + fi +else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..." + fi + if [ -n "$MVNW_REPOURL" ]; then + jarUrl="$MVNW_REPOURL/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + else + jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + fi + while IFS="=" read key value; do + case "$key" in (wrapperUrl) jarUrl="$value"; break ;; + esac + done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties" + if [ "$MVNW_VERBOSE" = true ]; then + echo "Downloading from: $jarUrl" + fi + wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" + if $cygwin; then + wrapperJarPath=`cygpath --path --windows "$wrapperJarPath"` + fi + + if command -v wget > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found wget ... using wget" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + wget "$jarUrl" -O "$wrapperJarPath" + else + wget --http-user=$MVNW_USERNAME --http-password=$MVNW_PASSWORD "$jarUrl" -O "$wrapperJarPath" + fi + elif command -v curl > /dev/null; then + if [ "$MVNW_VERBOSE" = true ]; then + echo "Found curl ... using curl" + fi + if [ -z "$MVNW_USERNAME" ] || [ -z "$MVNW_PASSWORD" ]; then + curl -o "$wrapperJarPath" "$jarUrl" -f + else + curl --user $MVNW_USERNAME:$MVNW_PASSWORD -o "$wrapperJarPath" "$jarUrl" -f + fi + + else + if [ "$MVNW_VERBOSE" = true ]; then + echo "Falling back to using Java to download" + fi + javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java" + # For Cygwin, switch paths to Windows format before running javac + if $cygwin; then + javaClass=`cygpath --path --windows "$javaClass"` + fi + if [ -e "$javaClass" ]; then + if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Compiling MavenWrapperDownloader.java ..." + fi + # Compiling the Java class + ("$JAVA_HOME/bin/javac" "$javaClass") + fi + if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then + # Running the downloader + if [ "$MVNW_VERBOSE" = true ]; then + echo " - Running MavenWrapperDownloader.java ..." + fi + ("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR") + fi + fi + fi +fi +########################################################################################## +# End of extension +########################################################################################## + +export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"} +if [ "$MVNW_VERBOSE" = true ]; then + echo $MAVEN_PROJECTBASEDIR +fi MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS" +# For Cygwin, switch paths to Windows format before running java +if $cygwin; then + [ -n "$M2_HOME" ] && + M2_HOME=`cygpath --path --windows "$M2_HOME"` + [ -n "$JAVA_HOME" ] && + JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"` + [ -n "$CLASSPATH" ] && + CLASSPATH=`cygpath --path --windows "$CLASSPATH"` + [ -n "$MAVEN_PROJECTBASEDIR" ] && + MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"` +fi + # Provide a "standardized" way to retrieve the CLI args that will # work with both Windows and non-Windows executions. MAVEN_CMD_LINE_ARGS="$MAVEN_CONFIG $@" @@ -226,20 +303,8 @@ export MAVEN_CMD_LINE_ARGS WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -echo "Running version check" -VERSION=$( sed '\!//' -e 's!.*$!!' ) -echo "The found version is [${VERSION}]" - -if echo $VERSION | egrep -q 'M|RC'; then - echo Activating \"milestone\" profile for version=\"$VERSION\" - echo $MAVEN_ARGS | grep -q milestone || MAVEN_ARGS="$MAVEN_ARGS -Pmilestone" -else - echo Deactivating \"milestone\" profile for version=\"$VERSION\" - echo $MAVEN_ARGS | grep -q milestone && MAVEN_ARGS=$(echo $MAVEN_ARGS | sed -e 's/-Pmilestone//') -fi - exec "$JAVACMD" \ $MAVEN_OPTS \ -classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \ "-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \ - ${WRAPPER_LAUNCHER} ${MAVEN_ARGS} "$@" + ${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@" diff --git a/mvnw.cmd b/mvnw.cmd index 4b98b78c..86115719 100644 --- a/mvnw.cmd +++ b/mvnw.cmd @@ -7,7 +7,7 @@ @REM "License"); you may not use this file except in compliance @REM with the License. You may obtain a copy of the License at @REM -@REM https://www.apache.org/licenses/LICENSE-2.0 +@REM http://www.apache.org/licenses/LICENSE-2.0 @REM @REM Unless required by applicable law or agreed to in writing, @REM software distributed under the License is distributed on an @@ -18,7 +18,7 @@ @REM ---------------------------------------------------------------------------- @REM ---------------------------------------------------------------------------- -@REM Maven2 Start Up Batch script +@REM Maven Start Up Batch script @REM @REM Required ENV vars: @REM JAVA_HOME - location of a JDK home dir @@ -26,7 +26,7 @@ @REM Optional ENV vars @REM M2_HOME - location of maven2's installed home dir @REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands -@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending +@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a keystroke before ending @REM MAVEN_OPTS - parameters passed to the Java VM when running Maven @REM e.g. to debug Maven itself, use @REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000 @@ -35,7 +35,9 @@ @REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on' @echo off -@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on' +@REM set title of command window +title %0 +@REM enable echoing by setting MAVEN_BATCH_ECHO to 'on' @if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO% @REM set %HOME% to equivalent of $HOME @@ -80,8 +82,6 @@ goto error :init -set MAVEN_CMD_LINE_ARGS=%* - @REM Find the project base dir, i.e. the directory that contains the folder ".mvn". @REM Fallback to current working directory if not found. @@ -117,11 +117,48 @@ for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do s :endReadAdditionalConfig SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe" - -set WRAPPER_JAR="".\.mvn\wrapper\maven-wrapper.jar"" +set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar" set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain -%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CMD_LINE_ARGS% +set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + +FOR /F "tokens=1,2 delims==" %%A IN ("%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties") DO ( + IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B +) + +@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central +@REM This allows using the maven wrapper in projects that prohibit checking in binary data. +if exist %WRAPPER_JAR% ( + if "%MVNW_VERBOSE%" == "true" ( + echo Found %WRAPPER_JAR% + ) +) else ( + if not "%MVNW_REPOURL%" == "" ( + SET DOWNLOAD_URL="%MVNW_REPOURL%/io/takari/maven-wrapper/0.5.6/maven-wrapper-0.5.6.jar" + ) + if "%MVNW_VERBOSE%" == "true" ( + echo Couldn't find %WRAPPER_JAR%, downloading it ... + echo Downloading from: %DOWNLOAD_URL% + ) + + powershell -Command "&{"^ + "$webclient = new-object System.Net.WebClient;"^ + "if (-not ([string]::IsNullOrEmpty('%MVNW_USERNAME%') -and [string]::IsNullOrEmpty('%MVNW_PASSWORD%'))) {"^ + "$webclient.Credentials = new-object System.Net.NetworkCredential('%MVNW_USERNAME%', '%MVNW_PASSWORD%');"^ + "}"^ + "[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; $webclient.DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"^ + "}" + if "%MVNW_VERBOSE%" == "true" ( + echo Finished downloading %WRAPPER_JAR% + ) +) +@REM End of extension + +@REM Provide a "standardized" way to retrieve the CLI args that will +@REM work with both Windows and non-Windows executions. +set MAVEN_CMD_LINE_ARGS=%* + +%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %* if ERRORLEVEL 1 goto error goto end @@ -142,4 +179,4 @@ if "%MAVEN_BATCH_PAUSE%" == "on" pause if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE% -exit /B %ERROR_CODE% \ No newline at end of file +exit /B %ERROR_CODE% diff --git a/pom.xml b/pom.xml index 6ec4e0ad..cca499ed 100644 --- a/pom.xml +++ b/pom.xml @@ -1,362 +1,70 @@ - - + + + 4.0.0 - - org.springframework.cloud - spring-cloud-build - 4.1.0-SNAPSHOT - - - - - spring-cloud-vault-parent - 4.1.0-SNAPSHOT - pom - - Spring Cloud Vault - Configuration Integration with HashiCorp Vault - - - spring-cloud-vault-dependencies - spring-cloud-vault-config - spring-cloud-vault-config-databases - spring-cloud-vault-config-consul - spring-cloud-vault-config-rabbitmq - spring-cloud-vault-config-aws - spring-cloud-starter-vault-config - docs - + org.springframework.cloud + spring-cloud-vault-docs-build + 0.0.1-SNAPSHOT + Spring Cloud Vault Docs Build + Builds Spring Cloud Vault Docs. + https://spring.io/projects/spring-cloud-vault - https://github.com/spring-cloud/spring-cloud-vault - scm:git:git://github.com/spring-cloud/spring-cloud-vault.git + scm:git:https://github.com/spring-cloud/spring-cloud-vault.git - scm:git:ssh://git@github.com/spring-cloud/spring-cloud-vault.git + scm:git:git@github.com:spring-cloud/spring-cloud-vault.git - HEAD + https://github.com/spring-cloud/spring-cloud-vault + + https://github.com/spring-cloud/spring-cloud-vault/issues + - UTF-8 - 4.1.0-SNAPSHOT - 1.70 - - v1-rev20201112-1.31.0 - 1.2.2 - 0.22.2 + 0.0.3 - - - - org.springframework.cloud - spring-cloud-commons-dependencies - ${spring-cloud-commons.version} - pom - import - - - - org.springframework.cloud - spring-cloud-vault-config - ${project.version} - test-jar - test - - - - org.springframework.cloud - spring-cloud-vault-dependencies - ${project.version} - import - pom - - - - - - - org.bouncycastle - bcpkix-jdk15on - ${bcpkix-jdk15on.version} - true - - - - - com.google.apis - google-api-services-iam - ${google-api-services-iam.version} - true - - - - com.google.cloud - google-cloud-iamcredentials - ${google-cloud-iamcredentials.version} - true - - - com.fasterxml.jackson.core - jackson-core - - - org.apache.httpcomponents - httpclient - - - commons-logging - commons-logging - - - - - - com.google.auth - google-auth-library-oauth2-http - ${google-auth-library-oauth2-http.version} - true - - - - - - - - jakarta.validation - jakarta.validation-api - provided - - - - org.hibernate.validator - hibernate-validator - provided - - - - org.springframework.boot - spring-boot-autoconfigure - provided - - - - org.springframework.boot - spring-boot-starter - provided - - - - - org.springframework.boot - spring-boot-starter-test - test - - - - org.assertj - assertj-core - 3.18.1 - test - - - - - - ../src/main/resources - META-INF - - - src/main/resources - - - - org.codehaus.mojo - flatten-maven-plugin - 1.2.5 - - - io.spring.javaformat - spring-javaformat-maven-plugin - - - org.apache.maven.plugins - maven-checkstyle-plugin + io.spring.maven.antora + antora-maven-plugin + ${io.spring.maven.antora-version} + true + + + + + + + + 9d489079e5ec46dbb238909fee5c9c29 + WB1FQYI187 + springcloudvault + + - - - - - org.apache.maven.plugins - maven-deploy-plugin - 2.8.2 - - - - org.apache.maven.plugins - maven-jar-plugin - 3.2.0 - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.2.0 - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - - - org.apache.maven.plugins - maven-source-plugin - 3.2.1 - - - - org.apache.maven.plugins - maven-surefire-plugin - 2.22.2 - - true - - - - - - - - org.apache.maven.plugins - maven-checkstyle-plugin - - - - - - - - sonar - - false - - - - - org.jacoco - jacoco-maven-plugin - 0.8.6 - - ${sonar.jacoco.reportPath} - true - - - - agent - - prepare-agent - - - - report - - report - - - - - - org.apache.maven.plugins - maven-surefire-plugin - - - - listener - org.sonar.java.jacoco.JUnitListener - - - - - - - - - spring - - true - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/release - - false - - - - - - spring-snapshots - Spring Snapshots - https://repo.spring.io/snapshot - - true - - - false - - - - spring-milestones - Spring Milestones - https://repo.spring.io/libs-milestone-local - - false - - - - spring-releases - Spring Releases - https://repo.spring.io/libs-release-local - - false - - - - - + + + spring-snapshot + https://repo.spring.io/snapshot + + true + + + false + + + + spring-milestone + https://repo.spring.io/milestone + + diff --git a/spring-cloud-starter-vault-config/.flattened-pom.xml b/spring-cloud-starter-vault-config/.flattened-pom.xml new file mode 100644 index 00000000..e57977a1 --- /dev/null +++ b/spring-cloud-starter-vault-config/.flattened-pom.xml @@ -0,0 +1,169 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-vault-parent + 4.1.0-SNAPSHOT + .. + + org.springframework.cloud + spring-cloud-starter-vault-config + 4.1.0-SNAPSHOT + Spring Cloud Starter Vault Config + Starter for exposing Spring Cloud Vault Config + https://cloud.spring.io/spring-cloud-vault/ + + Pivotal Software, Inc. + https://www.spring.io + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + Copyright 2014-2021 the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. + + See the License for the specific language governing permissions and + limitations under the License. + + + + + dsyer + Dave Syer + dsyer at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + sgibb + Spencer Gibb + sgibb at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + mgrzejszczak + Marcin Grzejszczak + mgrzejszczak at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + rbaxter + Ryan Baxter + rbaxter at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + omaciaszeksharma + Olga Maciaszek-Sharma + omaciaszeksharma at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + + scm:git:git://github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-starter-vault-config + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-starter-vault-config + https://github.com/spring-cloud/spring-cloud-vault/spring-cloud-starter-vault-config + + + + org.apache.httpcomponents.client5 + httpclient5 + 5.2.1 + compile + + + org.apache.httpcomponents.core5 + httpcore5 + 5.2.1 + compile + + + org.springframework.cloud + spring-cloud-starter + 4.1.0-SNAPSHOT + compile + + + org.springframework.cloud + spring-cloud-vault-config + 4.1.0-SNAPSHOT + compile + + + org.springframework.vault + spring-vault-core + 3.0.2 + compile + + + spring-core + org.springframework + + + spring-beans + org.springframework + + + spring-web + org.springframework + + + + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + + org.hibernate.validator + hibernate-validator + 8.0.0.Final + provided + + + org.springframework.boot + spring-boot-autoconfigure + 3.2.0-SNAPSHOT + provided + + + org.springframework.boot + spring-boot-starter + 3.2.0-SNAPSHOT + provided + + + diff --git a/spring-cloud-starter-vault-config/pom.xml b/spring-cloud-starter-vault-config/pom.xml deleted file mode 100644 index 841e2624..00000000 --- a/spring-cloud-starter-vault-config/pom.xml +++ /dev/null @@ -1,52 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-vault-parent - 4.1.0-SNAPSHOT - .. - - - spring-cloud-starter-vault-config - - Spring Cloud Starter Vault Config - Starter for exposing Spring Cloud Vault Config - - https://cloud.spring.io/spring-cloud-vault/ - - Pivotal Software, Inc. - https://www.spring.io - - - - - org.apache.httpcomponents.client5 - httpclient5 - - - - org.apache.httpcomponents.core5 - httpcore5 - - - - org.springframework.cloud - spring-cloud-starter - - - - org.springframework.cloud - spring-cloud-vault-config - - - - org.springframework.vault - spring-vault-core - - - - diff --git a/spring-cloud-starter-vault-config/src/main/resources/META-INF/spring.provides b/spring-cloud-starter-vault-config/src/main/resources/META-INF/spring.provides deleted file mode 100644 index a4491fb8..00000000 --- a/spring-cloud-starter-vault-config/src/main/resources/META-INF/spring.provides +++ /dev/null @@ -1 +0,0 @@ -provides: spring-cloud-vault-config \ No newline at end of file diff --git a/spring-cloud-vault-config-aws/.flattened-pom.xml b/spring-cloud-vault-config-aws/.flattened-pom.xml new file mode 100644 index 00000000..2172d6f3 --- /dev/null +++ b/spring-cloud-vault-config-aws/.flattened-pom.xml @@ -0,0 +1,145 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-vault-parent + 4.1.0-SNAPSHOT + .. + + org.springframework.cloud + spring-cloud-vault-config-aws + 4.1.0-SNAPSHOT + Spring Cloud Vault Config AWS support + Spring Cloud Vault Config AWS support + https://spring.io/spring-cloud/spring-cloud-vault-parent/spring-cloud-vault-config-aws + + Pivotal Software, Inc. + https://www.spring.io + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + Copyright 2014-2021 the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. + + See the License for the specific language governing permissions and + limitations under the License. + + + + + dsyer + Dave Syer + dsyer at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + sgibb + Spencer Gibb + sgibb at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + mgrzejszczak + Marcin Grzejszczak + mgrzejszczak at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + rbaxter + Ryan Baxter + rbaxter at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + omaciaszeksharma + Olga Maciaszek-Sharma + omaciaszeksharma at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + + scm:git:git://github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-config-aws + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-config-aws + https://github.com/spring-cloud/spring-cloud-vault/spring-cloud-vault-config-aws + + + + org.springframework.cloud + spring-cloud-vault-config + 4.1.0-SNAPSHOT + compile + + + org.springframework.boot + spring-boot-autoconfigure-processor + 3.2.0-SNAPSHOT + compile + true + + + org.springframework.boot + spring-boot-configuration-processor + 3.2.0-SNAPSHOT + compile + true + + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + + org.hibernate.validator + hibernate-validator + 8.0.0.Final + provided + + + org.springframework.boot + spring-boot-autoconfigure + 3.2.0-SNAPSHOT + provided + + + org.springframework.boot + spring-boot-starter + 3.2.0-SNAPSHOT + provided + + + diff --git a/spring-cloud-vault-config-aws/pom.xml b/spring-cloud-vault-config-aws/pom.xml deleted file mode 100644 index c8e75052..00000000 --- a/spring-cloud-vault-config-aws/pom.xml +++ /dev/null @@ -1,60 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-vault-parent - 4.1.0-SNAPSHOT - .. - - - spring-cloud-vault-config-aws - jar - - Spring Cloud Vault Config AWS support - Spring Cloud Vault Config AWS support - - - - - org.springframework.cloud - spring-cloud-vault-config - - - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - - org.junit.vintage - junit-vintage-engine - test - - - - io.netty - netty-all - test - - - - org.springframework.cloud - spring-cloud-vault-config - test-jar - - - - diff --git a/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/AwsCredentialType.java b/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/AwsCredentialType.java deleted file mode 100644 index 05733482..00000000 --- a/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/AwsCredentialType.java +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.aws; - -/** - * Supported AWS credential types. - * - * @author Kris Iyer - * @since 3.0.2 - */ -public enum AwsCredentialType { - - IAM_USER, ASSUMED_ROLE, FEDERATION_TOKEN - -} diff --git a/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/VaultAwsProperties.java b/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/VaultAwsProperties.java deleted file mode 100644 index 9db95ec2..00000000 --- a/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/VaultAwsProperties.java +++ /dev/null @@ -1,161 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.aws; - -import java.time.Duration; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor; -import org.springframework.lang.Nullable; - -/** - * Configuration properties for Vault using the AWS integration. - * - * @author Mark Paluch - * @author Kris Iyer - */ -@ConfigurationProperties("spring.cloud.vault.aws") -public class VaultAwsProperties implements VaultSecretBackendDescriptor { - - /** - * Enable aws backend usage. - */ - private boolean enabled; - - /** - * Role name for credentials. - */ - @Nullable - private String role; - - /** - * aws backend path. - */ - private String backend = "aws"; - - /** - * aws credential type - */ - private AwsCredentialType credentialType = AwsCredentialType.IAM_USER; - - /** - * Target property for the obtained access key. - */ - private String accessKeyProperty = "cloud.aws.credentials.accessKey"; - - /** - * Target property for the obtained secret key. - */ - private String secretKeyProperty = "cloud.aws.credentials.secretKey"; - - /** - * Target property for the obtained secret key. - */ - private String sessionTokenKeyProperty = "cloud.aws.credentials.sessionToken"; - - /** - * Role arn for assumed_role in case we have multiple roles associated with the vault - * role. - * @since 3.0.2 - */ - @Nullable - private String roleArn; - - /** - * TTL for sts tokens. Defaults to whatever the vault Role may have for Max. Also - * limited to what AWS supports to be the max for STS. - * @since 3.0.2 - */ - private Duration ttl = Duration.ZERO; - - @Override - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Nullable - public String getRole() { - return this.role; - } - - public void setRole(@Nullable String role) { - this.role = role; - } - - @Override - public String getBackend() { - return this.backend; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - public String getAccessKeyProperty() { - return this.accessKeyProperty; - } - - public void setAccessKeyProperty(String accessKeyProperty) { - this.accessKeyProperty = accessKeyProperty; - } - - public String getSecretKeyProperty() { - return this.secretKeyProperty; - } - - public void setSecretKeyProperty(String secretKeyProperty) { - this.secretKeyProperty = secretKeyProperty; - } - - public AwsCredentialType getCredentialType() { - return this.credentialType; - } - - public void setCredentialType(AwsCredentialType credentialType) { - this.credentialType = credentialType; - } - - public String getSessionTokenKeyProperty() { - return this.sessionTokenKeyProperty; - } - - public void setSessionTokenKeyProperty(String sessionTokenKeyProperty) { - this.sessionTokenKeyProperty = sessionTokenKeyProperty; - } - - @Nullable - public String getRoleArn() { - return this.roleArn; - } - - public void setRoleArn(String roleArn) { - this.roleArn = roleArn; - } - - public Duration getTtl() { - return this.ttl; - } - - public void setTtl(Duration ttl) { - this.ttl = ttl; - } - -} diff --git a/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsBootstrapConfiguration.java b/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsBootstrapConfiguration.java deleted file mode 100644 index 03a4f346..00000000 --- a/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsBootstrapConfiguration.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.aws; - -import java.util.HashMap; -import java.util.Map; -import java.util.StringJoiner; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.vault.config.LeasingSecretBackendMetadata; -import org.springframework.cloud.vault.config.PropertyNameTransformer; -import org.springframework.cloud.vault.config.SecretBackendMetadata; -import org.springframework.cloud.vault.config.SecretBackendMetadataFactory; -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.vault.core.lease.domain.RequestedSecret.Mode; -import org.springframework.vault.core.util.PropertyTransformer; - -/** - * Bootstrap configuration providing support for the AWS secret backend. - * - * @author Mark Paluch - * @author Kris Iyer - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties(VaultAwsProperties.class) -public class VaultConfigAwsBootstrapConfiguration { - - @Bean - @ConditionalOnMissingBean - public AwsSecretBackendMetadataFactory awsSecretBackendMetadataFactory() { - return new AwsSecretBackendMetadataFactory(); - } - - /** - * {@link SecretBackendMetadataFactory} for AWS integration using - * {@link VaultAwsProperties}. - */ - public static class AwsSecretBackendMetadataFactory implements SecretBackendMetadataFactory { - - /** - * Creates {@link SecretBackendMetadata} for a secret backend using - * {@link VaultAwsProperties}. This accessor transforms Vault's username/password - * property names to names provided with - * {@link VaultAwsProperties#getAccessKeyProperty()} and - * {@link VaultAwsProperties#getSecretKeyProperty()}. - * {@link VaultAwsProperties#getSessionTokenKeyProperty()}. - * @param properties must not be {@literal null}. - * @return the {@link SecretBackendMetadata} - */ - static SecretBackendMetadata forAws(final VaultAwsProperties properties) { - - Assert.notNull(properties, "VaultAwsProperties must not be null"); - - PropertyNameTransformer transformer = new PropertyNameTransformer(); - transformer.addKeyTransformation("access_key", properties.getAccessKeyProperty()); - transformer.addKeyTransformation("secret_key", properties.getSecretKeyProperty()); - - if (properties.getCredentialType() == AwsCredentialType.ASSUMED_ROLE - || properties.getCredentialType() == AwsCredentialType.FEDERATION_TOKEN) { - - // security token transformer for STS - transformer.addKeyTransformation("security_token", properties.getSessionTokenKeyProperty()); - - return new AwsStsLeasingSecretBackendMetadata(properties, transformer); - } - else { - return new AwsLeasingSecretBackendMetadata(properties, transformer); - } - } - - @Override - public SecretBackendMetadata createMetadata(VaultAwsProperties backendDescriptor) { - return forAws(backendDescriptor); - } - - @Override - public boolean supports(VaultSecretBackendDescriptor backendDescriptor) { - return backendDescriptor instanceof VaultAwsProperties; - } - - private static class AwsStsLeasingSecretBackendMetadata implements LeasingSecretBackendMetadata { - - private final VaultAwsProperties properties; - - private final PropertyNameTransformer transformer; - - AwsStsLeasingSecretBackendMetadata(VaultAwsProperties properties, PropertyNameTransformer transformer) { - this.properties = properties; - this.transformer = transformer; - } - - @Override - public String getName() { - return String.format("%s with Role %s", this.properties.getBackend(), this.properties.getRole()); - } - - @Override - public String getPath() { - - String defaultPath = "%s/sts/%s"; - StringJoiner joiner = new StringJoiner("&"); - - // ttl for assumed_role or federation_token - // pass through to let aws take care of min and max validations - // per the vault role - if (!this.properties.getTtl().isZero()) { - joiner.add("ttl=" + this.properties.getTtl().toMillis() + "ms"); - } - - // role_arn for assumed_role for vault role that has multiple role - // associations. - if (this.properties.getCredentialType() == AwsCredentialType.ASSUMED_ROLE - && StringUtils.hasText(this.properties.getRoleArn())) { - joiner.add("role_arn=" + this.properties.getRoleArn()); - } - - String pathToUse = joiner.length() == 0 ? defaultPath : defaultPath + "?" + joiner; - - return String.format(pathToUse, this.properties.getBackend(), this.properties.getRole()); - } - - @Override - public PropertyTransformer getPropertyTransformer() { - return this.transformer; - } - - @Override - public Map getVariables() { - - Map variables = new HashMap<>(); - - variables.put("backend", this.properties.getBackend()); - variables.put("key", String.format("sts/%s", this.properties.getRole())); - - return variables; - } - - @Override - public Mode getLeaseMode() { - return Mode.ROTATE; - } - - } - - private static class AwsLeasingSecretBackendMetadata implements SecretBackendMetadata { - - private final VaultAwsProperties properties; - - private final PropertyNameTransformer transformer; - - AwsLeasingSecretBackendMetadata(VaultAwsProperties properties, PropertyNameTransformer transformer) { - this.properties = properties; - this.transformer = transformer; - } - - @Override - public String getName() { - return String.format("%s with Role %s", this.properties.getBackend(), this.properties.getRole()); - } - - @Override - public String getPath() { - return String.format("%s/creds/%s", this.properties.getBackend(), this.properties.getRole()); - } - - @Override - public PropertyTransformer getPropertyTransformer() { - return this.transformer; - } - - @Override - public Map getVariables() { - - Map variables = new HashMap<>(); - - variables.put("backend", this.properties.getBackend()); - variables.put("key", String.format("creds/%s", this.properties.getRole())); - - return variables; - } - - } - - } - -} diff --git a/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/package-info.java b/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/package-info.java deleted file mode 100644 index 07e0bc8d..00000000 --- a/spring-cloud-vault-config-aws/src/main/java/org/springframework/cloud/vault/config/aws/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * AWS integration with Vault. - * @author Mark Paluch - */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields -package org.springframework.cloud.vault.config.aws; diff --git a/spring-cloud-vault-config-aws/src/main/resources/META-INF/spring.factories b/spring-cloud-vault-config-aws/src/main/resources/META-INF/spring.factories deleted file mode 100644 index b049588e..00000000 --- a/spring-cloud-vault-config-aws/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,9 +0,0 @@ -# Bootstrap Configuration -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.vault.config.aws.VaultConfigAwsBootstrapConfiguration - -org.springframework.cloud.vault.config.SecretBackendMetadataFactory=\ -org.springframework.cloud.vault.config.aws.VaultConfigAwsBootstrapConfiguration.AwsSecretBackendMetadataFactory - -org.springframework.cloud.vault.config.VaultSecretBackendDescriptor=\ -org.springframework.cloud.vault.config.aws.VaultAwsProperties diff --git a/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/AwsSecretIntegrationTests.java b/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/AwsSecretIntegrationTests.java deleted file mode 100644 index 1bb55bc6..00000000 --- a/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/AwsSecretIntegrationTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.aws; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import org.springframework.cloud.vault.config.VaultConfigOperations; -import org.springframework.cloud.vault.config.VaultConfigTemplate; -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.util.StringUtils; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; -import static org.springframework.cloud.vault.config.aws.VaultConfigAwsBootstrapConfiguration.AwsSecretBackendMetadataFactory.forAws; - -/** - * Integration tests for {@link VaultConfigTemplate} using the aws secret backend. This - * test requires AWS credentials and a region, see {@link #AWS_ACCESS_KEY} and - * {@link #AWS_SECRET_KEY} to be provided externally. - * - * @author Mark Paluch - */ -// FIXME: 4.0.0 -@Ignore("NoClassDefFoundError: org/springframework/http/client/Netty4ClientHttpRequestFactory") -public class AwsSecretIntegrationTests extends IntegrationTestSupport { - - private static final String AWS_REGION = "eu-west-1"; - - private static final String AWS_ACCESS_KEY = System.getProperty("aws.access.key"); - - private static final String AWS_SECRET_KEY = System.getProperty("aws.secret.key"); - - private static final String ARN = "arn:aws:iam::aws:policy/ReadOnlyAccess"; - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigOperations configOperations; - - private VaultAwsProperties aws = new VaultAwsProperties(); - - /** - * Initialize the aws secret backend. - */ - @Before - public void setUp() { - - assumeTrue(StringUtils.hasText(AWS_ACCESS_KEY) && StringUtils.hasText(AWS_SECRET_KEY)); - - this.aws.setEnabled(true); - this.aws.setRole("readonly"); - - if (!prepare().hasSecretBackend(this.aws.getBackend())) { - prepare().mountSecret(this.aws.getBackend()); - } - - VaultOperations vaultOperations = prepare().getVaultOperations(); - - Map connection = new HashMap<>(); - connection.put("region", AWS_REGION); - connection.put("access_key", AWS_ACCESS_KEY); - connection.put("secret_key", AWS_SECRET_KEY); - - vaultOperations.write(String.format("%s/config/root", this.aws.getBackend()), connection); - - vaultOperations.write(String.format("%s/roles/%s", this.aws.getBackend(), this.aws.getRole()), - Collections.singletonMap("arn", ARN)); - - this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties); - } - - @Test - public void shouldCreateCredentialsCorrectly() { - - Map secretProperties = this.configOperations.read(forAws(this.aws)).getData(); - - assertThat(secretProperties).containsKeys("cloud.aws.credentials.accessKey", "cloud.aws.credentials.secretKey"); - } - -} diff --git a/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsBootstrapConfigurationTests.java b/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsBootstrapConfigurationTests.java deleted file mode 100644 index e96d2629..00000000 --- a/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsBootstrapConfigurationTests.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.aws; - -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.config.KeyValueSecretBackendMetadata; -import org.springframework.cloud.vault.config.SecretBackendMetadata; -import org.springframework.cloud.vault.config.aws.VaultConfigAwsBootstrapConfiguration.AwsSecretBackendMetadataFactory; -import org.springframework.cloud.vault.config.aws.VaultConfigAwsBootstrapConfigurationTests.CustomBootstrapConfiguration; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link VaultConfigAwsBootstrapConfiguration}. - * - * @author Mark Paluch - */ -// FIXME: 4.0.0 -@Ignore("NoClassDefFoundError: org/springframework/http/client/Netty4ClientHttpRequestFactory") -@RunWith(SpringRunner.class) -@SpringBootTest(classes = CustomBootstrapConfiguration.class, - properties = { "VaultConfigAwsBootstrapConfigurationTests.custom.config=true", - "spring.cloud.vault.aws.role=foo", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigAwsBootstrapConfigurationTests extends IntegrationTestSupport { - - @Autowired - AwsSecretBackendMetadataFactory factory; - - @Autowired - VaultAwsProperties properties; - - @Test - public void shouldApplyCustomConfiguration() { - - SecretBackendMetadata metadata = this.factory.createMetadata(this.properties); - - assertThat(metadata).isInstanceOf(KeyValueSecretBackendMetadata.class); - assertThat(metadata.getPath()).isEqualTo(this.properties.getRole()); - } - - @Configuration(proxyBeanMethods = false) - public static class CustomBootstrapConfiguration { - - @Bean - @ConditionalOnProperty("VaultConfigAwsBootstrapConfigurationTests.custom.config") - AwsSecretBackendMetadataFactory customFactory() { - - return new AwsSecretBackendMetadataFactory() { - @Override - public SecretBackendMetadata createMetadata(VaultAwsProperties backendDescriptor) { - return KeyValueSecretBackendMetadata.create(backendDescriptor.getRole()); - } - }; - } - - } - -} diff --git a/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsBootstrapConfigurationUnitTests.java b/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsBootstrapConfigurationUnitTests.java deleted file mode 100644 index e52c3803..00000000 --- a/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsBootstrapConfigurationUnitTests.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.aws; - -import java.time.Duration; - -import org.junit.jupiter.api.Test; - -import org.springframework.cloud.vault.config.SecretBackendMetadata; -import org.springframework.cloud.vault.config.SecretBackendMetadataFactory; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link VaultConfigAwsBootstrapConfiguration}. - * - * @author Mark Paluch - */ -public class VaultConfigAwsBootstrapConfigurationUnitTests { - - @Test - void shouldCreateIamTokenSecretBackendMetadataFactory() { - - VaultAwsProperties properties = new VaultAwsProperties(); - properties.setRole("readonly"); - - SecretBackendMetadataFactory factory = new VaultConfigAwsBootstrapConfiguration() - .awsSecretBackendMetadataFactory(); - - SecretBackendMetadata metadata = factory.createMetadata(properties); - - assertThat(metadata.getPath()).isEqualTo("aws/creds/readonly"); - assertThat(metadata.getVariables()).containsEntry("backend", "aws").containsEntry("key", "creds/readonly"); - } - - @Test - void shouldCreateStsTokenSecretBackendMetadataFactory() { - - VaultAwsProperties properties = new VaultAwsProperties(); - properties.setCredentialType(AwsCredentialType.FEDERATION_TOKEN); - properties.setRole("readonly"); - - SecretBackendMetadataFactory factory = new VaultConfigAwsBootstrapConfiguration() - .awsSecretBackendMetadataFactory(); - - SecretBackendMetadata metadata = factory.createMetadata(properties); - - assertThat(metadata.getPath()).isEqualTo("aws/sts/readonly"); - assertThat(metadata.getVariables()).containsEntry("backend", "aws").containsEntry("key", "sts/readonly"); - } - - @Test - void shouldCreateStsTokenSecretBackendMetadataFactoryWithTtlAndRoleArn() { - - VaultAwsProperties properties = new VaultAwsProperties(); - properties.setCredentialType(AwsCredentialType.ASSUMED_ROLE); - properties.setRoleArn("1:2:3"); - properties.setTtl(Duration.ofMinutes(1)); - properties.setRole("readonly"); - - SecretBackendMetadataFactory factory = new VaultConfigAwsBootstrapConfiguration() - .awsSecretBackendMetadataFactory(); - - SecretBackendMetadata metadata = factory.createMetadata(properties); - - assertThat(metadata.getPath()).isEqualTo("aws/sts/readonly?ttl=60000ms&role_arn=1:2:3"); - assertThat(metadata.getVariables()).containsEntry("backend", "aws").containsEntry("key", "sts/readonly"); - } - -} diff --git a/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsTests.java b/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsTests.java deleted file mode 100644 index 04482c94..00000000 --- a/spring-cloud-vault-config-aws/src/test/java/org/springframework/cloud/vault/config/aws/VaultConfigAwsTests.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.aws; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.StringUtils; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the aws secret backend. In case this test should fail because - * of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - *

- * This test requires AWS credentials and a region, see {@link #AWS_ACCESS_KEY}, - * {@link #AWS_SECRET_KEY} and the {@link SpringBootTest} properties to be provided - * externally. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigAwsTests.TestApplication.class, - properties = { "spring.cloud.vault.aws.enabled=true", "spring.cloud.vault.aws.role=readonly", - "cloud.aws.region.auto=false", "cloud.aws.region.static=eu-west-1", - "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigAwsTests { - - private static final String AWS_REGION = "eu-west-1"; - - private static final String AWS_ACCESS_KEY = System.getProperty("aws.access.key"); - - private static final String AWS_SECRET_KEY = System.getProperty("aws.secret.key"); - - private static final String ARN = "arn:aws:iam::aws:policy/ReadOnlyAccess"; - - @Value("${cloud.aws.credentials.accessKey}") - String accessKey; - - @Value("${cloud.aws.credentials.secretKey}") - String secretKey; - - /** - * Initialize the aws secret backend. - */ - @BeforeClass - public static void beforeClass() { - - assumeTrue(StringUtils.hasText(AWS_ACCESS_KEY) && StringUtils.hasText(AWS_SECRET_KEY)); - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - if (!vaultRule.prepare().hasSecretBackend("aws")) { - vaultRule.prepare().mountSecret("aws"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - Map connection = new HashMap<>(); - connection.put("region", AWS_REGION); - connection.put("access_key", AWS_ACCESS_KEY); - connection.put("secret_key", AWS_SECRET_KEY); - - vaultOperations.write("aws/config/root", connection); - - vaultOperations.write("aws/roles/readonly", Collections.singletonMap("arn", ARN)); - } - - @Test - public void shouldInitializeAwsProperties() { - - assertThat(this.accessKey).isNotEmpty(); - assertThat(this.secretKey).isNotEmpty(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-aws/src/test/resources/META-INF/spring.factories b/spring-cloud-vault-config-aws/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 2d3527b3..00000000 --- a/spring-cloud-vault-config-aws/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,4 +0,0 @@ -# Bootstrap Configuration -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.vault.config.aws.VaultConfigAwsBootstrapConfigurationTests.CustomBootstrapConfiguration,\ -org.springframework.cloud.vault.config.aws.VaultConfigAwsBootstrapConfiguration diff --git a/spring-cloud-vault-config-aws/src/test/resources/bootstrap.yml b/spring-cloud-vault-config-aws/src/test/resources/bootstrap.yml deleted file mode 100644 index c598d962..00000000 --- a/spring-cloud-vault-config-aws/src/test/resources/bootstrap.yml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - application.name: testVaultApp - cloud.vault.token: 00000000-0000-0000-0000-000000000000 - cloud.vault.ssl.trust-store: file:../work/keystore.jks - cloud.vault.ssl.trust-store-password: changeit diff --git a/spring-cloud-vault-config-consul/.flattened-pom.xml b/spring-cloud-vault-config-consul/.flattened-pom.xml new file mode 100644 index 00000000..14b42e59 --- /dev/null +++ b/spring-cloud-vault-config-consul/.flattened-pom.xml @@ -0,0 +1,145 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-vault-parent + 4.1.0-SNAPSHOT + .. + + org.springframework.cloud + spring-cloud-vault-config-consul + 4.1.0-SNAPSHOT + Spring Cloud Vault Config Consul support + Spring Cloud Vault Config Consul support + https://spring.io/spring-cloud/spring-cloud-vault-parent/spring-cloud-vault-config-consul + + Pivotal Software, Inc. + https://www.spring.io + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + Copyright 2014-2021 the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. + + See the License for the specific language governing permissions and + limitations under the License. + + + + + dsyer + Dave Syer + dsyer at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + sgibb + Spencer Gibb + sgibb at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + mgrzejszczak + Marcin Grzejszczak + mgrzejszczak at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + rbaxter + Ryan Baxter + rbaxter at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + omaciaszeksharma + Olga Maciaszek-Sharma + omaciaszeksharma at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + + scm:git:git://github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-config-consul + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-config-consul + https://github.com/spring-cloud/spring-cloud-vault/spring-cloud-vault-config-consul + + + + org.springframework.cloud + spring-cloud-vault-config + 4.1.0-SNAPSHOT + compile + + + org.springframework.boot + spring-boot-autoconfigure-processor + 3.2.0-SNAPSHOT + compile + true + + + org.springframework.boot + spring-boot-configuration-processor + 3.2.0-SNAPSHOT + compile + true + + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + + org.hibernate.validator + hibernate-validator + 8.0.0.Final + provided + + + org.springframework.boot + spring-boot-autoconfigure + 3.2.0-SNAPSHOT + provided + + + org.springframework.boot + spring-boot-starter + 3.2.0-SNAPSHOT + provided + + + diff --git a/spring-cloud-vault-config-consul/pom.xml b/spring-cloud-vault-config-consul/pom.xml deleted file mode 100644 index 76e23a7a..00000000 --- a/spring-cloud-vault-config-consul/pom.xml +++ /dev/null @@ -1,88 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-vault-parent - 4.1.0-SNAPSHOT - .. - - - spring-cloud-vault-config-consul - Spring Cloud Vault Config Consul support - Spring Cloud Vault Config Consul support - - - 4.1.0-SNAPSHOT - - - - - - org.springframework.cloud - spring-cloud-vault-config - - - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - - org.junit.vintage - junit-vintage-engine - test - - - - org.apache.httpcomponents.client5 - httpclient5 - test - - - - org.springframework.cloud - spring-cloud-vault-config - test-jar - - - - org.springframework.cloud - spring-cloud-starter-consul-config - ${spring-cloud-consul.version} - test - - - org.springframework.cloud - spring-cloud-starter-ribbon - - - - - - org.springframework.cloud - spring-cloud-starter-consul-discovery - ${spring-cloud-consul.version} - test - - - org.springframework.cloud - spring-cloud-starter-ribbon - - - - - - diff --git a/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/ConsulBackendMetadata.java b/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/ConsulBackendMetadata.java deleted file mode 100644 index a8ff9113..00000000 --- a/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/ConsulBackendMetadata.java +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright 2013-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.consul; - -import java.util.HashMap; -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.vault.config.LeasingSecretBackendMetadata; -import org.springframework.context.ApplicationEvent; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.ApplicationEventPublisherAware; -import org.springframework.vault.core.lease.SecretLeaseContainer; -import org.springframework.vault.core.lease.domain.RequestedSecret; -import org.springframework.vault.core.lease.event.SecretLeaseCreatedEvent; -import org.springframework.vault.core.util.PropertyTransformer; - -/** - * @author Mark Paluch - */ -class ConsulBackendMetadata implements LeasingSecretBackendMetadata, ApplicationEventPublisherAware { - - private final Log log = LogFactory.getLog(getClass()); - - private final VaultConsulProperties properties; - - private final PropertyTransformer transformer; - - private ApplicationEventPublisher eventPublisher; - - ConsulBackendMetadata(VaultConsulProperties properties, PropertyTransformer transformer, - ApplicationEventPublisher eventPublisher) { - this.properties = properties; - this.transformer = transformer; - this.eventPublisher = eventPublisher; - } - - @Override - public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) { - this.eventPublisher = applicationEventPublisher; - } - - @Override - public String getName() { - return String.format("%s with Role %s", this.properties.getBackend(), this.properties.getRole()); - } - - @Override - public String getPath() { - return String.format("%s/creds/%s", this.properties.getBackend(), this.properties.getRole()); - } - - @Override - public Map getVariables() { - - Map variables = new HashMap<>(); - - variables.put("backend", this.properties.getBackend()); - variables.put("key", String.format("creds/%s", this.properties.getRole())); - - return variables; - } - - @Override - public PropertyTransformer getPropertyTransformer() { - return this.transformer; - } - - @Override - public RequestedSecret.Mode getLeaseMode() { - return RequestedSecret.Mode.ROTATE; - } - - @Override - public void afterRegistration(RequestedSecret secret, SecretLeaseContainer container) { - container.addLeaseListener(leaseEvent -> { - - if (leaseEvent.getSource() == secret && leaseEvent instanceof SecretLeaseCreatedEvent) { - if (this.log.isDebugEnabled()) { - this.log.debug("Publishing a RebindConsulEvent"); - } - this.eventPublisher.publishEvent(new RebindConsulEvent(this)); - } - }); - - // no need to rebind here since the transformer creats all appropriate properties. - } - - public static class RebindConsulEvent extends ApplicationEvent { - - RebindConsulEvent(Object source) { - super(source); - } - - } - -} diff --git a/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulAutoConfiguration.java b/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulAutoConfiguration.java deleted file mode 100644 index 5972cea1..00000000 --- a/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulAutoConfiguration.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.consul; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; -import org.springframework.cloud.vault.config.SecretBackendMetadataFactory; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationListener; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; - -/** - * Bootstrap configuration providing support for the Consul secret backend. - * - * @author Spencer Gibb - */ -@Configuration(proxyBeanMethods = false) -public class VaultConfigConsulAutoConfiguration { - - @Bean - @ConditionalOnMissingBean - public ConsulSecretRebindListener consulSecretRebindListener(ConfigurationPropertiesRebinder rebinder, - ConfigurableApplicationContext context) { - // TODO: some other way? Maybe a BootstrapApplicationContextHolder bean - // provided by spring cloud commons - ApplicationContext parent = context.getParent(); - if (parent != null) { - context = (ConfigurableApplicationContext) parent; - } - return new ConsulSecretRebindListener(rebinder, context); - } - - /** - * {@link SecretBackendMetadataFactory} for Consul integration using - * {@link VaultConsulProperties}. - */ - public static class ConsulSecretRebindListener - implements ApplicationListener { - - private final Log log = LogFactory.getLog(getClass()); - - private final ConfigurationPropertiesRebinder rebinder; - - public ConsulSecretRebindListener(ConfigurationPropertiesRebinder rebinder, - ConfigurableApplicationContext context) { - this.rebinder = rebinder; - context.addApplicationListener(this); - } - - @Override - public void onApplicationEvent(ConsulBackendMetadata.RebindConsulEvent event) { - if (this.log.isDebugEnabled()) { - this.log.debug("received RebindConsulEvent"); - } - rebind("consulDiscoveryProperties"); - rebind("consulConfigProperties"); - } - - private void rebind(String bean) { - - boolean success = this.rebinder.rebind(bean); - if (this.log.isInfoEnabled()) { - this.log.info(String.format( - "Attempted to rebind Consul bean '%s' with updated ACL token from vault, success: %s", bean, - success)); - } - } - - } - -} diff --git a/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulBootstrapConfiguration.java b/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulBootstrapConfiguration.java deleted file mode 100644 index 90895505..00000000 --- a/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulBootstrapConfiguration.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.consul; - -import java.util.LinkedHashMap; -import java.util.Map; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.vault.config.SecretBackendMetadata; -import org.springframework.cloud.vault.config.SecretBackendMetadataFactory; -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor; -import org.springframework.context.ApplicationContext; -import org.springframework.context.ApplicationEventPublisher; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.Assert; -import org.springframework.vault.core.util.PropertyTransformer; - -/** - * Bootstrap configuration providing support for the Consul secret backend. - * - * @author Mark Paluch - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties(VaultConsulProperties.class) -public class VaultConfigConsulBootstrapConfiguration { - - @Bean - @ConditionalOnMissingBean - public ConsulSecretBackendMetadataFactory consulSecretBackendMetadataFactory(ApplicationContext context) { - return new ConsulSecretBackendMetadataFactory(context); - } - - /** - * {@link SecretBackendMetadataFactory} for Consul integration using - * {@link VaultConsulProperties}. - */ - public static class ConsulSecretBackendMetadataFactory - implements SecretBackendMetadataFactory { - - private final ApplicationEventPublisher publisher; - - public ConsulSecretBackendMetadataFactory() { - this.publisher = event -> { - }; // NO-OP; - } - - public ConsulSecretBackendMetadataFactory(ApplicationContext publisher) { - this.publisher = publisher; - } - - public ApplicationEventPublisher getPublisher() { - return this.publisher; - } - - /** - * Creates a {@link SecretBackendMetadata} for a secret backend using - * {@link VaultConsulProperties}. This accessor transforms Vault's token property - * names to names provided with {@link VaultConsulProperties#getTokenProperty()}. - * @param properties must not be {@literal null}. - * @return the {@link SecretBackendMetadata} - */ - SecretBackendMetadata forConsul(VaultConsulProperties properties) { - - Assert.notNull(properties, "VaultConsulProperties must not be null"); - - /* - * PropertyNameTransformer transformer = new PropertyNameTransformer(); - * transformer.addKeyTransformation("token", properties.getTokenProperty()); - */ - - // spring.cloud.consul.token is a shortcut for initialization - // for this I couldn't get it to work without specifiying each property - // specifically - PropertyTransformer transformer = input -> { - - Map transformed = new LinkedHashMap<>(); - transformed.put("spring.cloud.consul.config.acl-token", input.get("token")); - transformed.put("spring.cloud.consul.discovery.acl-token", input.get("token")); - - return transformed; - }; - - return new ConsulBackendMetadata(properties, transformer, this.publisher); - } - - @Override - public SecretBackendMetadata createMetadata(VaultConsulProperties backendDescriptor) { - return forConsul(backendDescriptor); - } - - @Override - public boolean supports(VaultSecretBackendDescriptor backendDescriptor) { - return backendDescriptor instanceof VaultConsulProperties; - } - - } - -} diff --git a/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/VaultConsulProperties.java b/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/VaultConsulProperties.java deleted file mode 100644 index 1f5261ba..00000000 --- a/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/VaultConsulProperties.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.consul; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor; -import org.springframework.lang.Nullable; - -/** - * Configuration properties for HashiCorp Consul. - * - * @author Mark Paluch - */ -@ConfigurationProperties("spring.cloud.vault.consul") -public class VaultConsulProperties implements VaultSecretBackendDescriptor { - - /** - * Enable consul backend usage. - */ - private boolean enabled; - - /** - * Role name for credentials. - */ - @Nullable - private String role; - - /** - * Consul backend path. - */ - private String backend = "consul"; - - /** - * Target property for the obtained token. - */ - private String tokenProperty = "spring.cloud.consul.token"; - - @Override - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Nullable - public String getRole() { - return this.role; - } - - public void setRole(@Nullable String role) { - this.role = role; - } - - @Override - public String getBackend() { - return this.backend; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - public String getTokenProperty() { - return this.tokenProperty; - } - - public void setTokenProperty(String tokenProperty) { - this.tokenProperty = tokenProperty; - } - -} diff --git a/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/package-info.java b/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/package-info.java deleted file mode 100644 index c3111cb5..00000000 --- a/spring-cloud-vault-config-consul/src/main/java/org/springframework/cloud/vault/config/consul/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Consul integration with Vault. - * @author Mark Paluch - */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields -package org.springframework.cloud.vault.config.consul; diff --git a/spring-cloud-vault-config-consul/src/main/resources/META-INF/spring.factories b/spring-cloud-vault-config-consul/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 4cc99ff8..00000000 --- a/spring-cloud-vault-config-consul/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,9 +0,0 @@ -# Bootstrap Configuration -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.vault.config.consul.VaultConfigConsulBootstrapConfiguration - -org.springframework.cloud.vault.config.SecretBackendMetadataFactory=\ -org.springframework.cloud.vault.config.consul.VaultConfigConsulBootstrapConfiguration.ConsulSecretBackendMetadataFactory - -org.springframework.cloud.vault.config.VaultSecretBackendDescriptor=\ -org.springframework.cloud.vault.config.consul.VaultConsulProperties diff --git a/spring-cloud-vault-config-consul/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-cloud-vault-config-consul/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index f1e1cc21..00000000 --- a/spring-cloud-vault-config-consul/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1 +0,0 @@ -org.springframework.cloud.vault.config.consul.VaultConfigConsulAutoConfiguration diff --git a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/ConsulSecretIntegrationTests.java b/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/ConsulSecretIntegrationTests.java deleted file mode 100644 index a5c00780..00000000 --- a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/ConsulSecretIntegrationTests.java +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.consul; - -import java.util.Collections; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.config.VaultConfigOperations; -import org.springframework.cloud.vault.config.VaultConfigTemplate; -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.cloud.vault.config.consul.VaultConfigConsulBootstrapConfiguration.ConsulSecretBackendMetadataFactory; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.util.Base64Utils; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests for {@link VaultConfigTemplate} using the consul secret backend. This - * test requires a running Consul instance, see {@link #CONNECTION_URL}. - * - * @author Mark Paluch - */ -public class ConsulSecretIntegrationTests extends IntegrationTestSupport { - - private static final String POLICY = "key \"\" { policy = \"read\" }"; - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigOperations configOperations; - - private VaultConsulProperties consul = new VaultConsulProperties(); - - /** - * Initialize the consul secret backend. - */ - @Before - public void setUp() { - - assumeTrue(SetupConsul.isConsulAvailable()); - - this.consul.setEnabled(true); - this.consul.setRole("readonly"); - - if (!prepare().hasSecretBackend(this.consul.getBackend())) { - prepare().mountSecret(this.consul.getBackend()); - } - - VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations(); - - SetupConsul.setupConsul(vaultOperations, this.consul.getBackend()); - - vaultOperations.write(String.format("%s/roles/%s", this.consul.getBackend(), this.consul.getRole()), - Collections.singletonMap("policy", Base64Utils.encodeToString(POLICY.getBytes()))); - - this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties); - } - - @Test - public void shouldCreateCredentialsCorrectly() { - - ConsulSecretBackendMetadataFactory factory = new ConsulSecretBackendMetadataFactory(null); - Map secretProperties = this.configOperations.read(factory.forConsul(this.consul)).getData(); - - assertThat(secretProperties).containsKeys("spring.cloud.consul.config.acl-token", - "spring.cloud.consul.discovery.acl-token"); - } - -} diff --git a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/DiscoveryBootstrapConfigurationTests.java b/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/DiscoveryBootstrapConfigurationTests.java deleted file mode 100644 index 2fb6c9f7..00000000 --- a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/DiscoveryBootstrapConfigurationTests.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.consul; - -import java.net.InetSocketAddress; -import java.util.List; - -import com.ecwid.consul.v1.ConsulClient; -import com.ecwid.consul.v1.QueryParams; -import com.ecwid.consul.v1.Response; -import com.ecwid.consul.v1.agent.model.NewService; -import com.ecwid.consul.v1.catalog.model.CatalogService; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.support.VaultHealth; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Tests for {@link DiscoveryBootstrapConfigurationTests}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(properties = { "spring.cloud.vault.discovery.enabled=true" }) -@Ignore("Consul discovery client is set up in the main context, no longer in the bootstrap context") -public class DiscoveryBootstrapConfigurationTests extends IntegrationTestSupport { - - private static final String CONSUL_HOST = "localhost"; - - private static final int CONSUL_PORT = 8500; - - @Autowired - VaultOperations vaultOperations; - - @BeforeClass - public static void beforeClass() { - - assumeTrue(CanConnect.to(new InetSocketAddress(CONSUL_HOST, CONSUL_PORT))); - - ConsulClient client = new ConsulClient(); - - Response> response = client.getCatalogService("vault", QueryParams.DEFAULT); - - if (response.getValue().isEmpty()) { - - NewService service = new NewService(); - service.setAddress("localhost"); - service.setPort(8200); - service.setId("vault"); - service.setName("vault"); - - client.agentServiceRegister(service); - } - } - - @Test - public void shouldDiscoverThroughConsul() { - - VaultHealth health = this.vaultOperations.opsForSys().health(); - - assertThat(health).isNotNull(); - } - -} diff --git a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/SetupConsul.java b/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/SetupConsul.java deleted file mode 100644 index c5728dfe..00000000 --- a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/SetupConsul.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2020-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.consul; - -import java.net.InetSocketAddress; -import java.util.HashMap; -import java.util.Map; - -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.vault.core.VaultOperations; -import org.springframework.web.client.HttpStatusCodeException; -import org.springframework.web.client.RestTemplate; - -import static org.junit.Assume.assumeFalse; - -/** - * Utility to setup Consul. - * - * @author Mark Paluch - */ -class SetupConsul { - - static final String CONSUL_HOST = "localhost"; - - static final int CONSUL_PORT = 8500; - - private static final String CONNECTION_URL = String.format("%s:%d", CONSUL_HOST, CONSUL_PORT); - - private static final ParameterizedTypeReference> STRING_MAP = new ParameterizedTypeReference>() { - }; - - private static final String CONSUL_ACL_MASTER_TOKEN = "consul-master-token"; - - static void setupConsul(VaultOperations vaultOperations, String consulBackend) { - - RestTemplate restTemplate = new RestTemplate(); - - HttpHeaders headers = new HttpHeaders(); - headers.add("X-Consul-Token", CONSUL_ACL_MASTER_TOKEN); - HttpEntity requestEntity = new HttpEntity<>("{\"Name\": \"sample\", \"Type\": \"management\"}", - headers); - - try { - ResponseEntity> tokenResponse = restTemplate.exchange( - "http://{host}:{port}/v1/acl/create", HttpMethod.PUT, requestEntity, STRING_MAP, CONSUL_HOST, - CONSUL_PORT); - - Map consulAccess = new HashMap<>(); - consulAccess.put("address", CONNECTION_URL); - consulAccess.put("token", tokenResponse.getBody().get("ID")); - - vaultOperations.write(String.format("%s/config/access", consulBackend), consulAccess); - } - catch (HttpStatusCodeException e) { - - assumeFalse("Skipping because Consul is not configured as we expect it to be", - e.getStatusCode().is4xxClientError()); - - throw e; - } - } - - static boolean isConsulAvailable() { - return CanConnect.to(new InetSocketAddress(CONSUL_HOST, CONSUL_PORT)); - } - -} diff --git a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulBootstrapConfigurationTests.java b/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulBootstrapConfigurationTests.java deleted file mode 100644 index 29a70fc8..00000000 --- a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulBootstrapConfigurationTests.java +++ /dev/null @@ -1,81 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.consul; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.context.properties.ConfigurationPropertiesRebinder; -import org.springframework.cloud.vault.config.KeyValueSecretBackendMetadata; -import org.springframework.cloud.vault.config.SecretBackendMetadata; -import org.springframework.cloud.vault.config.consul.VaultConfigConsulBootstrapConfiguration.ConsulSecretBackendMetadataFactory; -import org.springframework.cloud.vault.config.consul.VaultConfigConsulBootstrapConfigurationTests.CustomBootstrapConfiguration; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link VaultConfigConsulBootstrapConfigurationTests}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = CustomBootstrapConfiguration.class, - properties = { "VaultConfigConsulBootstrapConfigurationTests.custom.config=true", - "spring.cloud.vault.consul.role=foo", "spring.cloud.vault.consul.enabled=true", - "spring.cloud.consul.config.enabled=false", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigConsulBootstrapConfigurationTests extends IntegrationTestSupport { - - @Autowired - ConsulSecretBackendMetadataFactory factory; - - @Autowired - VaultConsulProperties properties; - - @Test - public void shouldApplyCustomConfiguration() { - - SecretBackendMetadata metadata = this.factory.createMetadata(this.properties); - - assertThat(metadata).isInstanceOf(KeyValueSecretBackendMetadata.class); - assertThat(metadata.getPath()).isEqualTo(this.properties.getRole()); - } - - @Configuration(proxyBeanMethods = false) - public static class CustomBootstrapConfiguration { - - @Bean - @ConditionalOnProperty("VaultConfigConsulBootstrapConfigurationTests.custom.config") - ConsulSecretBackendMetadataFactory customFactory(ConfigurationPropertiesRebinder rebinder) { - - return new ConsulSecretBackendMetadataFactory(null) { - @Override - public SecretBackendMetadata createMetadata(VaultConsulProperties backendDescriptor) { - return KeyValueSecretBackendMetadata.create(backendDescriptor.getRole()); - } - }; - } - - } - -} diff --git a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulConfigDataTests.java b/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulConfigDataTests.java deleted file mode 100644 index 04d4144f..00000000 --- a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulConfigDataTests.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.consul; - -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.concurrent.BlockingQueue; -import java.util.concurrent.LinkedBlockingQueue; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.event.EventListener; -import org.springframework.util.Base64Utils; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Tests for {@link VaultConfigConsulConfigDataTests}. - * - * @author Mark Paluch - */ -public class VaultConfigConsulConfigDataTests extends IntegrationTestSupport { - - private static final String POLICY = "key \"\" { policy = \"read\" }"; - - private ConfigurableApplicationContext context; - - @Before - public void before() { - - assumeTrue(SetupConsul.isConsulAvailable()); - - VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations(); - - if (!prepare().hasSecretBackend("consul")) { - prepare().mountSecret("consul"); - } - - SetupConsul.setupConsul(vaultOperations, "consul"); - - Map role = new LinkedHashMap<>(); - role.put("policy", Base64Utils.encodeToString(POLICY.getBytes())); - role.put("ttl", "3s"); - role.put("max_ttl", "3s"); - vaultOperations.write(String.format("%s/roles/%s", "consul", "short-readonly"), role); - - this.vaultRule.prepare().getVaultOperations().write("secret/VaultConfigConsulConfigDataTests", - Collections.singletonMap("default-key", "default")); - - SpringApplication application = new SpringApplication(VaultConfigConsulConfigDataTests.Config.class); - application.setWebApplicationType(WebApplicationType.NONE); - - this.context = application.run("--spring.application.name=VaultConfigConsulConfigDataTests", - "--spring.config.import=vault:", "--spring.cloud.vault.kv.enabled=false", - "--spring.cloud.vault.config.lifecycle.min-renewal=2s", "--spring.cloud.vault.consul.enabled=true", - "--spring.cloud.vault.consul.role=short-readonly", - "--spring.cloud.vault.token=" + Settings.token().getToken()); - } - - @Test - public void shouldApplyConfigurer() throws InterruptedException { - - Config config = this.context.getBean(Config.class); - - assertThat(config.events).isEmpty(); - assertThat(this.context.getEnvironment().getProperty("spring.cloud.consul.config.acl-token")).isNotNull(); - - Thread.sleep(5_000); - assertThat(config.events).isNotEmpty(); - } - - @After - public void after() { - if (this.context != null) { - this.context.close(); - } - } - - @SpringBootConfiguration(proxyBeanMethods = false) - @EnableAutoConfiguration - static class Config { - - final BlockingQueue events = new LinkedBlockingQueue<>(); - - @EventListener - public void onRebind(ConsulBackendMetadata.RebindConsulEvent rebindConsulEvent) { - this.events.add(rebindConsulEvent); - } - - } - -} diff --git a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulTests.java b/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulTests.java deleted file mode 100644 index 2531fde3..00000000 --- a/spring-cloud-vault-config-consul/src/test/java/org/springframework/cloud/vault/config/consul/VaultConfigConsulTests.java +++ /dev/null @@ -1,169 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.consul; - -import java.net.InetSocketAddress; -import java.util.Base64; -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.consul.config.ConsulConfigProperties; -import org.springframework.cloud.consul.discovery.ConsulDiscoveryProperties; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.core.ParameterizedTypeReference; -import org.springframework.core.env.Environment; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.ResponseEntity; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; -import org.springframework.web.client.HttpStatusCodeException; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Java6Assertions.assertThat; -import static org.junit.Assume.assumeFalse; -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the consul secret backend. In case this test should fail - * because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - * @author Spencer Gibb - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigConsulTests.TestApplication.class, - properties = { "spring.cloud.vault.consul.enabled=true", "spring.cloud.vault.consul.role=readonly", - "spring.cloud.consul.discovery.catalog-services-watch.enabled=false", - "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigConsulTests { - - private static final String CONSUL_HOST = "localhost"; - - private static final int CONSUL_PORT = 8500; - - private static final String CONNECTION_URL = String.format("%s:%d", CONSUL_HOST, CONSUL_PORT); - - private static final String POLICY = "key \"\" { policy = \"read\" }"; - - private static final String CONSUL_ACL_MASTER_TOKEN = "consul-master-token"; - - private static final ParameterizedTypeReference> STRING_MAP = new ParameterizedTypeReference>() { - }; - - @Value("${spring.cloud.consul.discovery.acl-token:}") - String discoveryToken; - - @Value("${spring.cloud.consul.config.acl-token:}") - String configToken; - - @Autowired - Environment env; - - @Autowired - ConsulDiscoveryProperties discoveryProperties; - - @Autowired - ConsulConfigProperties configProperties; - - /** - * Initialize the consul secret backend. - */ - @BeforeClass - public static void beforeClass() { - - assumeTrue(CanConnect.to(new InetSocketAddress(CONSUL_HOST, CONSUL_PORT))); - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - if (!vaultRule.prepare().hasSecretBackend("consul")) { - vaultRule.prepare().mountSecret("consul"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - RestTemplate restTemplate = new RestTemplate(); - - HttpHeaders headers = new HttpHeaders(); - headers.add("X-Consul-Token", CONSUL_ACL_MASTER_TOKEN); - HttpEntity requestEntity = new HttpEntity<>("{\"Name\": \"sample\", \"Type\": \"management\"}", - headers); - - try { - ResponseEntity> tokenResponse = restTemplate.exchange( - "http://{host}:{port}/v1/acl/create", HttpMethod.PUT, requestEntity, STRING_MAP, CONSUL_HOST, - CONSUL_PORT); - - Map consulAccess = new HashMap<>(); - consulAccess.put("address", CONNECTION_URL); - consulAccess.put("token", tokenResponse.getBody().get("ID")); - - vaultOperations.write("consul/config/access", consulAccess); - - Map role = new LinkedHashMap<>(); - role.put("policy", new String(Base64.getEncoder().encode(POLICY.getBytes()))); - role.put("ttl", "5s"); - role.put("max_ttl", "5s"); - - vaultOperations.write("consul/roles/readonly", role); - } - catch (HttpStatusCodeException e) { - - assumeFalse("Skipping because Consul is not configured as we expect it to be", - e.getStatusCode().is4xxClientError()); - - throw e; - } - } - - @Test - public void shouldHaveRenewedToken() throws InterruptedException { - assertThat(configToken).isNotEmpty(); - assertThat(discoveryToken).isNotEmpty(); - assertThat(this.configProperties.getAclToken()).isEqualTo(configToken); - assertThat(this.discoveryProperties.getAclToken()).isEqualTo(discoveryToken); - - Thread.sleep(8_000L); - - assertThat(this.configProperties.getAclToken()).isNotEmpty().isNotEqualTo(configToken); - assertThat(this.discoveryProperties.getAclToken()).isNotEmpty().isNotEqualTo(discoveryToken); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-consul/src/test/resources/META-INF/spring.factories b/spring-cloud-vault-config-consul/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 4625be75..00000000 --- a/spring-cloud-vault-config-consul/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,3 +0,0 @@ -# Bootstrap Configuration -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.vault.config.consul.VaultConfigConsulBootstrapConfigurationTests.CustomBootstrapConfiguration diff --git a/spring-cloud-vault-config-consul/src/test/resources/bootstrap.yml b/spring-cloud-vault-config-consul/src/test/resources/bootstrap.yml deleted file mode 100644 index 307f7807..00000000 --- a/spring-cloud-vault-config-consul/src/test/resources/bootstrap.yml +++ /dev/null @@ -1,8 +0,0 @@ -spring: - application.name: testVaultApp - cloud.vault.token: 00000000-0000-0000-0000-000000000000 - cloud.vault.ssl.trust-store: file:../work/keystore.jks - cloud.vault.ssl.trust-store-password: changeit - cloud.vault.config.lifecycle.min-renewal: 3s - cloud.vault.config.lifecycle.expiry-threshold: 3s - diff --git a/spring-cloud-vault-config-databases/.flattened-pom.xml b/spring-cloud-vault-config-databases/.flattened-pom.xml new file mode 100644 index 00000000..4e83453f --- /dev/null +++ b/spring-cloud-vault-config-databases/.flattened-pom.xml @@ -0,0 +1,145 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-vault-parent + 4.1.0-SNAPSHOT + .. + + org.springframework.cloud + spring-cloud-vault-config-databases + 4.1.0-SNAPSHOT + Spring Cloud Vault Config Database support + Spring Cloud Vault Config Database support + https://spring.io/spring-cloud/spring-cloud-vault-parent/spring-cloud-vault-config-databases + + Pivotal Software, Inc. + https://www.spring.io + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + Copyright 2014-2021 the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. + + See the License for the specific language governing permissions and + limitations under the License. + + + + + dsyer + Dave Syer + dsyer at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + sgibb + Spencer Gibb + sgibb at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + mgrzejszczak + Marcin Grzejszczak + mgrzejszczak at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + rbaxter + Ryan Baxter + rbaxter at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + omaciaszeksharma + Olga Maciaszek-Sharma + omaciaszeksharma at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + + scm:git:git://github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-config-databases + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-config-databases + https://github.com/spring-cloud/spring-cloud-vault/spring-cloud-vault-config-databases + + + + org.springframework.cloud + spring-cloud-vault-config + 4.1.0-SNAPSHOT + compile + + + org.springframework.boot + spring-boot-autoconfigure-processor + 3.2.0-SNAPSHOT + compile + true + + + org.springframework.boot + spring-boot-configuration-processor + 3.2.0-SNAPSHOT + compile + true + + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + + org.hibernate.validator + hibernate-validator + 8.0.0.Final + provided + + + org.springframework.boot + spring-boot-autoconfigure + 3.2.0-SNAPSHOT + provided + + + org.springframework.boot + spring-boot-starter + 3.2.0-SNAPSHOT + provided + + + diff --git a/spring-cloud-vault-config-databases/pom.xml b/spring-cloud-vault-config-databases/pom.xml deleted file mode 100644 index 3580166f..00000000 --- a/spring-cloud-vault-config-databases/pom.xml +++ /dev/null @@ -1,113 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-vault-parent - 4.1.0-SNAPSHOT - .. - - - spring-cloud-vault-config-databases - Spring Cloud Vault Config Database support - Spring Cloud Vault Config Database support - - - - - org.springframework.cloud - spring-cloud-vault-config - - - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - - org.junit.vintage - junit-vintage-engine - test - - - - com.datastax.oss - java-driver-core - test - - - - com.couchbase.client - java-client - test - - - - com.h2database - h2 - test - - - - com.mysql - mysql-connector-j - test - - - - org.apache.httpcomponents.client5 - httpclient5 - test - - - - org.mongodb - mongodb-driver-core - test - - - - org.postgresql - postgresql - test - - - - org.springframework.cloud - spring-cloud-vault-config - test-jar - - - - org.springframework.boot - spring-boot-starter-data-mongodb - test - - - - org.springframework.boot - spring-boot-starter-jdbc - test - - - - - - - diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/DatabaseSecretProperties.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/DatabaseSecretProperties.java deleted file mode 100644 index f7019d03..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/DatabaseSecretProperties.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor; - -/** - * Configuration properties interface for database secrets. - * - * @author Mark Paluch - * @author Sebastien Nahelou - */ -public interface DatabaseSecretProperties extends VaultSecretBackendDescriptor { - - /** - * Role name. - * @return the role name - */ - String getRole(); - - /** - * Whether the configuration uses static roles. - * @return {@literal true} if the configuration uses static roles. - * @since 2.2 - */ - boolean isStaticRole(); - - /** - * Backend path. - * @return the backend path. - */ - String getBackend(); - - /** - * @return name of the target property for the obtained username. - */ - String getUsernameProperty(); - - /** - * @return name of the target property for the obtained password. - */ - String getPasswordProperty(); - -} diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultCassandraProperties.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultCassandraProperties.java deleted file mode 100644 index eafa8659..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultCassandraProperties.java +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.lang.Nullable; -import org.springframework.validation.annotation.Validated; - -/** - * Configuration properties for Vault using the Apache Cassandra integration. - * - * @author Mark Paluch - * @author Sebastien Nahelou - */ -@ConfigurationProperties("spring.cloud.vault.cassandra") -@Validated -public class VaultCassandraProperties implements DatabaseSecretProperties { - - /** - * Enable cassandra backend usage. - */ - private boolean enabled; - - /** - * Role name for credentials. - */ - @Nullable - private String role; - - /** - * Enable static role usage. - * - * @since 2.2 - */ - private boolean staticRole; - - /** - * Cassandra backend path. - */ - private String backend = "cassandra"; - - /** - * Target property for the obtained username. - */ - private String usernameProperty = "spring.data.cassandra.username"; - - /** - * Target property for the obtained password. - */ - private String passwordProperty = "spring.data.cassandra.password"; - - @Override - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - @Nullable - public String getRole() { - return this.role; - } - - public void setRole(@Nullable String role) { - this.role = role; - } - - @Override - public boolean isStaticRole() { - return this.staticRole; - } - - public void setStaticRole(boolean staticRole) { - this.staticRole = staticRole; - } - - @Override - public String getBackend() { - return this.backend; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - @Override - public String getUsernameProperty() { - return this.usernameProperty; - } - - public void setUsernameProperty(String usernameProperty) { - this.usernameProperty = usernameProperty; - } - - @Override - public String getPasswordProperty() { - return this.passwordProperty; - } - - public void setPasswordProperty(String passwordProperty) { - this.passwordProperty = passwordProperty; - } - -} diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfiguration.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfiguration.java deleted file mode 100644 index 278971e4..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfiguration.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.vault.config.PropertyNameTransformer; -import org.springframework.cloud.vault.config.SecretBackendMetadata; -import org.springframework.cloud.vault.config.SecretBackendMetadataFactory; -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.util.Assert; -import org.springframework.vault.core.util.PropertyTransformer; - -import java.util.HashMap; -import java.util.Map; - -/** - * Bootstrap configuration providing support for the Database secret backends such as - * Database, Apache Cassandra, Couchbase and MongoDB. - * - * @author Mark Paluch - * @author Per Abich - * @author Sebastien Nahelou - * @author Francis Hitchens - * @author Quintin Beukes - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties({ VaultMySqlProperties.class, VaultPostgreSqlProperties.class, - VaultCassandraProperties.class, VaultCouchbaseProperties.class, VaultMongoProperties.class, - VaultElasticsearchProperties.class, VaultDatabaseProperties.class, VaultDatabasesProperties.class }) -@Order(Ordered.LOWEST_PRECEDENCE - 15) -public class VaultConfigDatabaseBootstrapConfiguration { - - @Bean - @ConditionalOnMissingBean - public DatabaseSecretBackendMetadataFactory databaseSecretBackendMetadataFactory() { - return new DatabaseSecretBackendMetadataFactory(); - } - - /** - * {@link SecretBackendMetadataFactory} for Database integration using - * {@link DatabaseSecretProperties}. - */ - public static class DatabaseSecretBackendMetadataFactory - implements SecretBackendMetadataFactory { - - /** - * Creates a {@link SecretBackendMetadata} for a secret backend using - * {@link DatabaseSecretProperties}. This accessor transforms Vault's - * username/password property names to names provided with - * {@link DatabaseSecretProperties#getUsernameProperty()} and - * {@link DatabaseSecretProperties#getPasswordProperty()}. - * @param properties must not be {@literal null}. - * @return the {@link SecretBackendMetadata} - */ - static SecretBackendMetadata forDatabase(final DatabaseSecretProperties properties) { - - Assert.notNull(properties, "DatabaseSecretProperties must not be null"); - - PropertyNameTransformer transformer = new PropertyNameTransformer(); - transformer.addKeyTransformation("username", properties.getUsernameProperty()); - transformer.addKeyTransformation("password", properties.getPasswordProperty()); - - return new SecretBackendMetadata() { - - private final String credPath = properties.isStaticRole() ? "static-creds" : "creds"; - - @Override - public String getName() { - return String.format("%s with Role %s", properties.getBackend(), properties.getRole()); - } - - @Override - public String getPath() { - return String.format("%s/%s/%s", properties.getBackend(), this.credPath, properties.getRole()); - } - - @Override - public PropertyTransformer getPropertyTransformer() { - return transformer; - } - - @Override - public Map getVariables() { - - Map variables = new HashMap<>(); - variables.put("backend", properties.getBackend()); - variables.put("key", String.format("%s/%s", this.credPath, properties.getRole())); - return variables; - } - }; - } - - @Override - public SecretBackendMetadata createMetadata(DatabaseSecretProperties backendDescriptor) { - return forDatabase(backendDescriptor); - } - - @Override - public boolean supports(VaultSecretBackendDescriptor backendDescriptor) { - return backendDescriptor instanceof DatabaseSecretProperties; - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultCouchbaseProperties.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultCouchbaseProperties.java deleted file mode 100644 index 4d1393e6..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultCouchbaseProperties.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.lang.Nullable; - -/** - * Configuration properties for Vault using the Couchbase integration. - * - * @author Francis Hitchens - */ -@ConfigurationProperties("spring.cloud.vault.couchbase") -public class VaultCouchbaseProperties implements DatabaseSecretProperties { - - /** - * Enable couchbase backend usage. - */ - private boolean enabled = false; - - /** - * Role name for credentials. - */ - @Nullable - private String role; - - /** - * Enable static role usage. - * - */ - private boolean staticRole = false; - - /** - * Couchbase backend path. - */ - private String backend = "database"; - - /** - * Target property for the obtained username. - */ - private String usernameProperty = "spring.couchbase.username"; - - /** - * Target property for the obtained password. - */ - private String passwordProperty = "spring.couchbase.password"; - - @Override - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - @Nullable - public String getRole() { - return this.role; - } - - public void setRole(@Nullable String role) { - this.role = role; - } - - @Override - public boolean isStaticRole() { - return this.staticRole; - } - - public void setStaticRole(boolean staticRole) { - this.staticRole = staticRole; - } - - @Override - public String getBackend() { - return this.backend; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - @Override - public String getUsernameProperty() { - return this.usernameProperty; - } - - public void setUsernameProperty(String usernameProperty) { - this.usernameProperty = usernameProperty; - } - - @Override - public String getPasswordProperty() { - return this.passwordProperty; - } - - public void setPasswordProperty(String passwordProperty) { - this.passwordProperty = passwordProperty; - } - -} diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultDatabaseProperties.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultDatabaseProperties.java deleted file mode 100644 index d1e8abde..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultDatabaseProperties.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.lang.Nullable; - -/** - * Configuration properties for Vault using the Database integration. - * - * @author Per Abich - * @author Sebastien Nahelou - * @since 2.0 - */ -@ConfigurationProperties("spring.cloud.vault.database") -public class VaultDatabaseProperties implements DatabaseSecretProperties { - - /** - * Enable database backend usage. - */ - private boolean enabled = false; - - /** - * Role name for credentials. - */ - @Nullable - private String role; - - /** - * Enable static role usage. - */ - private boolean staticRole = false; - - /** - * Database backend path. - */ - private String backend = "database"; - - /** - * Target property for the obtained username. - */ - private String usernameProperty = "spring.datasource.username"; - - /** - * Target property for the obtained password. - */ - private String passwordProperty = "spring.datasource.password"; - - @Override - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - @Nullable - public String getRole() { - return this.role; - } - - public void setRole(@Nullable String role) { - this.role = role; - } - - @Override - public boolean isStaticRole() { - return this.staticRole; - } - - public void setStaticRole(boolean staticRole) { - this.staticRole = staticRole; - } - - @Override - public String getBackend() { - return this.backend; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - @Override - public String getUsernameProperty() { - return this.usernameProperty; - } - - public void setUsernameProperty(String usernameProperty) { - this.usernameProperty = usernameProperty; - } - - @Override - public String getPasswordProperty() { - return this.passwordProperty; - } - - public void setPasswordProperty(String passwordProperty) { - this.passwordProperty = passwordProperty; - } - -} diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultDatabasesProperties.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultDatabasesProperties.java deleted file mode 100644 index a48dddfd..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultDatabasesProperties.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor; -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptorFactory; - -import java.util.Collection; -import java.util.HashMap; -import java.util.Map; - -/** - * Configuration properties for multiple database secrets using the {@code database} - * backend. This is configured with the {@code spring.cloud.vault.databases.*} mapping. - * - * @author Quintin Beukes - * @author Mark Paluch - * @since 3.0.3 - */ -@ConfigurationProperties("spring.cloud.vault") -public class VaultDatabasesProperties implements VaultSecretBackendDescriptorFactory { - - private Map databases = new HashMap<>(); - - public Map getDatabases() { - return this.databases; - } - - public void setDatabases(Map databases) { - this.databases = databases; - } - - @Override - public Collection create() { - return getDatabases().values(); - } - -} diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultElasticsearchProperties.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultElasticsearchProperties.java deleted file mode 100644 index f8130c57..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultElasticsearchProperties.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.lang.Nullable; - -/** - * Configuration properties for Vault using the Elasticsearch integration. - * - * @author Mark Paluch - * @since 3.0 - */ -@ConfigurationProperties("spring.cloud.vault.elasticsearch") -public class VaultElasticsearchProperties implements DatabaseSecretProperties { - - /** - * Enable elasticsearch backend usage. - */ - private boolean enabled; - - /** - * Role name for credentials. - */ - @Nullable - private String role; - - /** - * Enable static role usage. - */ - private boolean staticRole; - - /** - * Database backend path. - */ - private String backend = "database"; - - /** - * Target property for the obtained username. - */ - private String usernameProperty = "spring.elasticsearch.rest.username"; - - /** - * Target property for the obtained password. - */ - private String passwordProperty = "spring.elasticsearch.rest.password"; - - @Override - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - @Nullable - public String getRole() { - return this.role; - } - - public void setRole(@Nullable String role) { - this.role = role; - } - - @Override - public boolean isStaticRole() { - return this.staticRole; - } - - public void setStaticRole(boolean staticRole) { - this.staticRole = staticRole; - } - - @Override - public String getBackend() { - return this.backend; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - @Override - public String getUsernameProperty() { - return this.usernameProperty; - } - - public void setUsernameProperty(String usernameProperty) { - this.usernameProperty = usernameProperty; - } - - @Override - public String getPasswordProperty() { - return this.passwordProperty; - } - - public void setPasswordProperty(String passwordProperty) { - this.passwordProperty = passwordProperty; - } - -} diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultMongoProperties.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultMongoProperties.java deleted file mode 100644 index bac3377f..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultMongoProperties.java +++ /dev/null @@ -1,119 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.lang.Nullable; - -/** - * Configuration properties for Vault using the MongoDB integration. - * - * @author Mark Paluch - * @author Sebastien Nahelou - */ -@ConfigurationProperties("spring.cloud.vault.mongodb") -public class VaultMongoProperties implements DatabaseSecretProperties { - - /** - * Enable mongodb backend usage. - */ - private boolean enabled; - - /** - * Role name for credentials. - */ - @Nullable - private String role; - - /** - * Enable static role usage. - * - * @since 2.2 - */ - private boolean staticRole; - - /** - * MongoDB backend path. - */ - private String backend = "mongodb"; - - /** - * Target property for the obtained username. - */ - private String usernameProperty = "spring.data.mongodb.username"; - - /** - * Target property for the obtained password. - */ - private String passwordProperty = "spring.data.mongodb.password"; - - @Override - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - @Nullable - public String getRole() { - return this.role; - } - - public void setRole(@Nullable String role) { - this.role = role; - } - - @Override - public boolean isStaticRole() { - return this.staticRole; - } - - public void setStaticRole(boolean staticRole) { - this.staticRole = staticRole; - } - - @Override - public String getBackend() { - return this.backend; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - @Override - public String getUsernameProperty() { - return this.usernameProperty; - } - - public void setUsernameProperty(String usernameProperty) { - this.usernameProperty = usernameProperty; - } - - @Override - public String getPasswordProperty() { - return this.passwordProperty; - } - - public void setPasswordProperty(String passwordProperty) { - this.passwordProperty = passwordProperty; - } - -} diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultMySqlProperties.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultMySqlProperties.java deleted file mode 100644 index 4696e002..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultMySqlProperties.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor; -import org.springframework.lang.Nullable; - -/** - * Configuration properties for Vault using the MySQL integration. - * - * @author Mark Paluch - * @deprecated since 2.0. Use {@link VaultDatabaseProperties} or - * {@link VaultDatabasesProperties}. - */ -@ConfigurationProperties("spring.cloud.vault.mysql") -@Deprecated -public class VaultMySqlProperties implements DatabaseSecretProperties, VaultSecretBackendDescriptor { - - /** - * Enable mysql backend usage. - */ - private boolean enabled = false; - - /** - * Role name for credentials. - */ - @Nullable - private String role; - - /** - * mysql backend path. - */ - private String backend = "mysql"; - - /** - * Target property for the obtained username. - */ - private String usernameProperty = "spring.datasource.username"; - - /** - * Target property for the obtained username. - */ - private String passwordProperty = "spring.datasource.password"; - - @Override - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - @Nullable - public String getRole() { - return this.role; - } - - public void setRole(@Nullable String role) { - this.role = role; - } - - @Override - public boolean isStaticRole() { - return false; - } - - @Override - public String getBackend() { - return this.backend; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - @Override - public String getUsernameProperty() { - return this.usernameProperty; - } - - public void setUsernameProperty(String usernameProperty) { - this.usernameProperty = usernameProperty; - } - - @Override - public String getPasswordProperty() { - return this.passwordProperty; - } - - public void setPasswordProperty(String passwordProperty) { - this.passwordProperty = passwordProperty; - } - -} diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultPostgreSqlProperties.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultPostgreSqlProperties.java deleted file mode 100644 index 93c08212..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/VaultPostgreSqlProperties.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.lang.Nullable; - -/** - * Configuration properties for Vault using the PostgreSQL integration. - * - * @author Mark Paluch - * @deprecated since 2.0. Use {@link VaultDatabaseProperties} or - * {@link VaultDatabasesProperties}. - */ -@ConfigurationProperties("spring.cloud.vault.postgresql") -@Deprecated -public class VaultPostgreSqlProperties implements DatabaseSecretProperties { - - /** - * Enable postgresql backend usage. - */ - @Deprecated - private boolean enabled = false; - - /** - * Role name for credentials. - */ - @Nullable - private String role; - - /** - * postgresql backend path. - */ - private String backend = "postgresql"; - - /** - * Target property for the obtained username. - */ - private String usernameProperty = "spring.datasource.username"; - - /** - * Target property for the obtained username. - */ - private String passwordProperty = "spring.datasource.password"; - - @Override - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Override - @Nullable - public String getRole() { - return this.role; - } - - public void setRole(@Nullable String role) { - this.role = role; - } - - @Override - public boolean isStaticRole() { - return false; - } - - @Override - public String getBackend() { - return this.backend; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - @Override - public String getUsernameProperty() { - return this.usernameProperty; - } - - public void setUsernameProperty(String usernameProperty) { - this.usernameProperty = usernameProperty; - } - - @Override - public String getPasswordProperty() { - return this.passwordProperty; - } - - public void setPasswordProperty(String passwordProperty) { - this.passwordProperty = passwordProperty; - } - -} diff --git a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/package-info.java b/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/package-info.java deleted file mode 100644 index 3d68f775..00000000 --- a/spring-cloud-vault-config-databases/src/main/java/org/springframework/cloud/vault/config/databases/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Database integration with Vault. - * @author Mark Paluch - */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields -package org.springframework.cloud.vault.config.databases; diff --git a/spring-cloud-vault-config-databases/src/main/resources/META-INF/spring.factories b/spring-cloud-vault-config-databases/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 6a44ee66..00000000 --- a/spring-cloud-vault-config-databases/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,18 +0,0 @@ -# Bootstrap Configuration -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration - -org.springframework.cloud.vault.config.SecretBackendMetadataFactory=\ -org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory - -org.springframework.cloud.vault.config.VaultSecretBackendDescriptor=\ -org.springframework.cloud.vault.config.databases.VaultCassandraProperties,\ -org.springframework.cloud.vault.config.databases.VaultCouchbaseProperties,\ -org.springframework.cloud.vault.config.databases.VaultDatabaseProperties,\ -org.springframework.cloud.vault.config.databases.VaultElasticsearchProperties,\ -org.springframework.cloud.vault.config.databases.VaultMongoProperties,\ -org.springframework.cloud.vault.config.databases.VaultMySqlProperties,\ -org.springframework.cloud.vault.config.databases.VaultPostgreSqlProperties - -org.springframework.cloud.vault.config.VaultSecretBackendDescriptorFactory=\ -org.springframework.cloud.vault.config.databases.VaultDatabasesProperties diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/CassandraSecretIntegrationTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/CassandraSecretIntegrationTests.java deleted file mode 100644 index c3f1bf95..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/CassandraSecretIntegrationTests.java +++ /dev/null @@ -1,108 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.config.VaultConfigOperations; -import org.springframework.cloud.vault.config.VaultConfigTemplate; -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; -import static org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory.forDatabase; - -/** - * Integration tests for {@link VaultConfigTemplate} using the cassandra secret backend. - * This test requires a running Cassandra instance, see {@link #CASSANDRA_HOST} and other - * {@code CASSANDRA_*} properties. - * - * @author Mark Paluch - */ -public class CassandraSecretIntegrationTests extends IntegrationTestSupport { - - private static final String CASSANDRA_HOST = "localhost"; - - private static final int CASSANDRA_PORT = 9042; - - private static final String CASSANDRA_USERNAME = "springvault"; - - private static final String CASSANDRA_PASSWORD = "springvault"; - - private static final String CREATE_USER_AND_GRANT_CQL = "CREATE USER '{{username}}' WITH PASSWORD '{{password}}' NOSUPERUSER;" - + "GRANT SELECT ON ALL KEYSPACES TO {{username}};"; - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigOperations configOperations; - - private VaultCassandraProperties cassandra = new VaultCassandraProperties(); - - /** - * Initialize cassandra secret backend. - */ - @Before - public void setUp() { - - assumeTrue(CanConnect.to(new InetSocketAddress(CASSANDRA_HOST, CASSANDRA_PORT))); - - this.cassandra.setEnabled(true); - this.cassandra.setRole("readonly"); - - if (!prepare().hasSecretBackend(this.cassandra.getBackend())) { - prepare().mountSecret(this.cassandra.getBackend()); - } - - VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations(); - - Map connection = new HashMap<>(); - connection.put("hosts", CASSANDRA_HOST); - connection.put("username", CASSANDRA_USERNAME); - connection.put("password", CASSANDRA_PASSWORD); - connection.put("protocol_version", 3); - - vaultOperations.write(String.format("%s/config/connection", this.cassandra.getBackend()), connection); - - Map role = new HashMap<>(); - - role.put("creation_cql", CREATE_USER_AND_GRANT_CQL); - role.put("consistency", "All"); - - vaultOperations.write(String.format("%s/roles/%s", this.cassandra.getBackend(), this.cassandra.getRole()), - role); - - this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties); - } - - @Test - public void shouldCreateCredentialsCorrectly() { - - Map secretProperties = this.configOperations.read(forDatabase(this.cassandra)).getData(); - - assertThat(secretProperties).containsKeys("spring.data.cassandra.username", "spring.data.cassandra.password"); - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/CouchbaseSecretIntegrationTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/CouchbaseSecretIntegrationTests.java deleted file mode 100644 index a06a4595..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/CouchbaseSecretIntegrationTests.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.config.VaultConfigOperations; -import org.springframework.cloud.vault.config.VaultConfigTemplate; -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.Version; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; -import static org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory.forDatabase; - -/** - * Integration tests for {@link VaultConfigTemplate} using the couchbase secret backend. - * This test requires a running Couchbase instance, see {@link #COUCHBASE_HOST}. - * - * @author Mark Paluch - */ -public class CouchbaseSecretIntegrationTests extends IntegrationTestSupport { - - private static final int COUCHBASE_PORT = 8091; - - private static final String COUCHBASE_HOST = "localhost"; - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigOperations configOperations; - - private VaultCouchbaseProperties couchbaseProperties = new VaultCouchbaseProperties(); - - /** - * Initialize couchbase secret backend. - */ - @Before - public void setUp() { - - assumeTrue(CanConnect.to(new InetSocketAddress(COUCHBASE_HOST, COUCHBASE_PORT))); - assumeTrue(this.vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("1.3.0"))); - - this.couchbaseProperties.setEnabled(true); - this.couchbaseProperties.setRole("couchbase-readonly"); - - if (!prepare().hasSecretBackend(this.couchbaseProperties.getBackend())) { - prepare().mountSecret(this.couchbaseProperties.getBackend()); - } - - VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations(); - - Map config = new HashMap<>(); - config.put("plugin_name", "couchbase-database-plugin"); - config.put("hosts", "couchbase://localhost"); - config.put("username", "Administrator"); - config.put("password", "password"); - config.put("allowed_roles", "*"); - - vaultOperations.write("database/config/spring-cloud-vault-couchbase", config); - - Map body = new HashMap<>(); - body.put("db_name", "spring-cloud-vault-couchbase"); - body.put("creation_statements", "{\"roles\":[{\"role\":\"ro_admin\"}]}"); - - vaultOperations.write("database/roles/couchbase-readonly", body); - - this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties); - } - - @Test - public void shouldCreateCredentialsCorrectly() { - - Map secretProperties = this.configOperations.read(forDatabase(this.couchbaseProperties)) - .getData(); - - assertThat(secretProperties).containsKeys("spring.couchbase.username", "spring.couchbase.password"); - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/ElasticsearchSecretIntegrationTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/ElasticsearchSecretIntegrationTests.java deleted file mode 100644 index 7a085e27..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/ElasticsearchSecretIntegrationTests.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.config.VaultConfigOperations; -import org.springframework.cloud.vault.config.VaultConfigTemplate; -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.Version; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; -import static org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory.forDatabase; - -/** - * Integration tests for {@link VaultConfigTemplate} using the elasticsearch database - * backend. This test requires a running Elasticearch instance, see - * {@link #ELASTICSEARCH_HOST}. Make sure to configure {#link ES_HOME} accordingly. - * - * @author Mark Paluch - */ -public class ElasticsearchSecretIntegrationTests extends IntegrationTestSupport { - - private static final int ELASTICSEARCH_PORT = 9200; - - private static final String ELASTICSEARCH_HOST = "localhost"; - - private static final String ES_HOME = "configure me"; - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigOperations configOperations; - - private VaultElasticsearchProperties elasticsearch = new VaultElasticsearchProperties(); - - /** - * Initialize the elasticsearch secret backend. - */ - @Before - public void setUp() { - - assumeTrue(CanConnect.to(new InetSocketAddress(ELASTICSEARCH_HOST, ELASTICSEARCH_PORT))); - assumeTrue(prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("1.3.0"))); - - this.elasticsearch.setEnabled(true); - this.elasticsearch.setRole("readonly"); - - if (!prepare().hasSecretBackend(this.elasticsearch.getBackend())) { - prepare().mountSecret(this.elasticsearch.getBackend()); - } - - VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations(); - String database = "elasticsearch"; - - Map config = new LinkedHashMap<>(); - config.put("plugin_name", "elasticsearch-database-plugin"); - config.put("allowed_roles", "readonly"); - config.put("username", "elastic"); - config.put("password", "elastic"); - config.put("url", String.format("http://%s:%d", ELASTICSEARCH_HOST, ELASTICSEARCH_PORT)); - - config.put("ca_cert", String.format("%s/elastic-stack-ca.crt", ES_HOME)); - config.put("client_cert", String.format("%s/elastic-certificates.crt", ES_HOME)); - config.put("client_key", String.format("%s/elastic-certificates.key", ES_HOME)); - - vaultOperations.write(String.format("%s/config/%s", this.elasticsearch.getBackend(), database), config); - - Map role = new LinkedHashMap<>(); - role.put("db_name", database); - role.put("creation_statements", - "{\"elasticsearch_role_definition\": {\"indices\": [{\"names\":[\"*\"], \"privileges\":[\"read\"]}]}}"); - role.put("default_ttl", "1h"); - - vaultOperations.write(this.elasticsearch.getBackend() + "/roles/" + this.elasticsearch.getRole(), role); - - this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties); - } - - @Test - public void shouldCreateCredentialsCorrectly() { - - Map secretProperties = this.configOperations.read(forDatabase(this.elasticsearch)).getData(); - - assertThat(secretProperties).containsKeys("spring.elasticsearch.rest.username", - "spring.elasticsearch.rest.password"); - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MongoSecretIntegrationTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MongoSecretIntegrationTests.java deleted file mode 100644 index 5dccc277..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MongoSecretIntegrationTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.config.VaultConfigOperations; -import org.springframework.cloud.vault.config.VaultConfigTemplate; -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.Version; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; -import static org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory.forDatabase; - -/** - * Integration tests for {@link VaultConfigTemplate} using the mongodb secret backend. - * This test requires a running MongoDB instance, see {@link #ROOT_CREDENTIALS}. - * - * @author Mark Paluch - */ -public class MongoSecretIntegrationTests extends IntegrationTestSupport { - - private static final int MONGODB_PORT = 27017; - - private static final String MONGODB_HOST = "localhost"; - - private static final String ROOT_CREDENTIALS = String - .format("mongodb://springvault:springvault@%s:%d/admin?ssl=false", MONGODB_HOST, MONGODB_PORT); - - private static final String ROLES = "[ \"readWrite\", { \"role\": \"read\", \"db\": \"admin\" } ]"; - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigOperations configOperations; - - private VaultMongoProperties mongodb = new VaultMongoProperties(); - - /** - * Initialize the mongodb secret backend. - */ - @Before - public void setUp() { - - assumeTrue(CanConnect.to(new InetSocketAddress(MONGODB_HOST, MONGODB_PORT))); - assumeTrue(prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.2"))); - - this.mongodb.setEnabled(true); - this.mongodb.setRole("readonly"); - - if (!prepare().hasSecretBackend(this.mongodb.getBackend())) { - prepare().mountSecret(this.mongodb.getBackend()); - } - - VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations(); - - vaultOperations.write(String.format("%s/config/connection", this.mongodb.getBackend()), - Collections.singletonMap("uri", ROOT_CREDENTIALS)); - - Map role = new HashMap<>(); - role.put("db", "admin"); - role.put("roles", ROLES); - - vaultOperations.write(String.format("%s/roles/%s", this.mongodb.getBackend(), this.mongodb.getRole()), role); - - this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties); - } - - @Test - public void shouldCreateCredentialsCorrectly() { - - Map secretProperties = this.configOperations.read(forDatabase(this.mongodb)).getData(); - - assertThat(secretProperties).containsKeys("spring.data.mongodb.username", "spring.data.mongodb.password"); - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MySqlDatabaseSecretIntegrationTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MySqlDatabaseSecretIntegrationTests.java deleted file mode 100644 index b5dd3c94..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MySqlDatabaseSecretIntegrationTests.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.config.VaultConfigOperations; -import org.springframework.cloud.vault.config.VaultConfigTemplate; -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.Version; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; -import static org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory.forDatabase; - -/** - * Integration tests for {@link VaultConfigTemplate} using the {@code database} secret - * backend with {@code mysql-legacy-database-plugin}. This test requires a running MySQL - * instance, see {@link #ROOT_CREDENTIALS}. - * - * @author Mark Paluch - */ -public class MySqlDatabaseSecretIntegrationTests extends IntegrationTestSupport { - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigOperations configOperations; - - @SuppressWarnings("deprecation") - private VaultMySqlProperties mySql = new VaultMySqlProperties(); - - /** - * Initialize the mysql secret backend. - */ - @Before - public void setUp() { - - assumeTrue(CanConnect.to(new InetSocketAddress(MySqlFixtures.MYSQL_HOST, MySqlFixtures.MYSQL_PORT))); - assumeTrue(prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.7.1"))); - - this.mySql.setEnabled(true); - this.mySql.setRole("readonly"); - this.mySql.setBackend("database"); - - MySqlFixtures.setupMysql(this.vaultRule); - - this.configOperations = new VaultConfigTemplate(this.vaultRule.prepare().getVaultOperations(), - this.vaultProperties); - } - - @Test - public void shouldCreateCredentialsCorrectly() { - - Map secretProperties = this.configOperations.read(forDatabase(this.mySql)).getData(); - - assertThat(secretProperties).containsKeys("spring.datasource.username", "spring.datasource.password"); - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MySqlFixtures.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MySqlFixtures.java deleted file mode 100644 index f267753d..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MySqlFixtures.java +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.vault.core.VaultOperations; - -/** - * @author Mark Paluch - */ -class MySqlFixtures { - - static final int MYSQL_PORT = 3306; - - static final String MYSQL_HOST = "localhost"; - - static final String JDBC_URL = "jdbc:mysql://" + MYSQL_HOST + ":" + MYSQL_PORT - + "/mysql?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true"; - - static final String ROOT_CREDENTIALS = String.format("springvault:springvault@tcp(%s:%d)/", MYSQL_HOST, MYSQL_PORT); - - static final String CREATE_USER_AND_GRANT_SQL = "CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';" - + "GRANT SELECT ON *.* TO '{{name}}'@'%';"; - - public static void setupMysql(VaultRule vaultRule) { - - if (!vaultRule.prepare().hasSecretBackend("database")) { - vaultRule.prepare().mountSecret("database"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - Map config = new HashMap<>(); - config.put("plugin_name", "mysql-legacy-database-plugin"); - config.put("connection_url", ROOT_CREDENTIALS); - config.put("allowed_roles", "readonly"); - - vaultOperations.write("database/config/mysql", config); - - Map body = new HashMap<>(); - body.put("db_name", "mysql"); - body.put("creation_statements", CREATE_USER_AND_GRANT_SQL); - - vaultOperations.write("database/roles/readonly", body); - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MySqlSecretIntegrationTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MySqlSecretIntegrationTests.java deleted file mode 100644 index 2e7817bf..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/MySqlSecretIntegrationTests.java +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.util.Collections; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.config.VaultConfigOperations; -import org.springframework.cloud.vault.config.VaultConfigTemplate; -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; -import static org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory.forDatabase; - -/** - * Integration tests for {@link VaultConfigTemplate} using the mysql secret backend. This - * test requires a running MySQL instance, see {@link #ROOT_CREDENTIALS}. - * - * @author Mark Paluch - */ -public class MySqlSecretIntegrationTests extends IntegrationTestSupport { - - private static final int MYSQL_PORT = 3306; - - private static final String MYSQL_HOST = "localhost"; - - private static final String ROOT_CREDENTIALS = String.format("springvault:springvault@tcp(%s:%d)/", MYSQL_HOST, - MYSQL_PORT); - - private static final String CREATE_USER_AND_GRANT_SQL = "CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';" - + "GRANT SELECT ON *.* TO '{{name}}'@'%';"; - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigOperations configOperations; - - @SuppressWarnings("deprecation") - private VaultMySqlProperties mySql = new VaultMySqlProperties(); - - /** - * Initialize the mysql secret backend. - */ - @Before - public void setUp() { - - assumeTrue(CanConnect.to(new InetSocketAddress(MYSQL_HOST, MYSQL_PORT))); - - this.mySql.setEnabled(true); - this.mySql.setRole("readonly"); - - if (!prepare().hasSecretBackend(this.mySql.getBackend())) { - prepare().mountSecret(this.mySql.getBackend()); - } - - VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations(); - - vaultOperations.write(String.format("%s/config/connection", this.mySql.getBackend()), - Collections.singletonMap("connection_url", ROOT_CREDENTIALS)); - - vaultOperations.write(String.format("%s/roles/%s", this.mySql.getBackend(), this.mySql.getRole()), - Collections.singletonMap("sql", CREATE_USER_AND_GRANT_SQL)); - - this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties); - } - - @Test - public void shouldCreateCredentialsCorrectly() { - - Map secretProperties = this.configOperations.read(forDatabase(this.mySql)).getData(); - - assertThat(secretProperties).containsKeys("spring.datasource.username", "spring.datasource.password"); - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/PostgreSqlSecretIntegrationTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/PostgreSqlSecretIntegrationTests.java deleted file mode 100644 index c2c6b379..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/PostgreSqlSecretIntegrationTests.java +++ /dev/null @@ -1,101 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.util.Collections; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.config.VaultConfigOperations; -import org.springframework.cloud.vault.config.VaultConfigTemplate; -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; -import static org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory.forDatabase; - -/** - * Integration tests for - * {@link org.springframework.cloud.vault.config.VaultConfigTemplate} using the postgresql - * secret backend. This test requires a running PostgreSQL instance, see - * {@link #CONNECTION_URL}. - * - * @author Mark Paluch - */ -public class PostgreSqlSecretIntegrationTests extends IntegrationTestSupport { - - private static final String POSTGRES_HOST = "localhost"; - - private static final int POSTGRES_PORT = 5432; - - private static final String CONNECTION_URL = String.format( - "postgresql://springvault:springvault@%s:%d/postgres?sslmode=disable", POSTGRES_HOST, POSTGRES_PORT); - - private static final String CREATE_USER_AND_GRANT_SQL = "CREATE ROLE \"{{name}}\" WITH " - + "LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';\n" - + "GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";"; - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigOperations configOperations; - - @SuppressWarnings("deprecation") - private VaultPostgreSqlProperties postgreSql = new VaultPostgreSqlProperties(); - - /** - * Initialize the postgresql secret backend. - */ - @Before - public void setUp() { - - assumeTrue(CanConnect.to(new InetSocketAddress(POSTGRES_HOST, POSTGRES_PORT))); - - this.postgreSql.setEnabled(true); - this.postgreSql.setRole("readonly"); - - if (!prepare().hasSecretBackend(this.postgreSql.getBackend())) { - prepare().mountSecret(this.postgreSql.getBackend()); - } - - VaultOperations vaultOperations = this.vaultRule.prepare().getVaultOperations(); - - vaultOperations.write(String.format("%s/config/connection", this.postgreSql.getBackend()), - Collections.singletonMap("connection_url", CONNECTION_URL)); - - vaultOperations.write(String.format("%s/roles/%s", this.postgreSql.getBackend(), this.postgreSql.getRole()), - Collections.singletonMap("sql", CREATE_USER_AND_GRANT_SQL)); - - this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties); - - } - - @Test - public void shouldCreateCredentialsCorrectly() { - - Map secretProperties = this.configOperations.read(forDatabase(this.postgreSql)).getData(); - - assertThat(secretProperties).containsKeys("spring.datasource.username", "spring.datasource.password"); - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigCassandraTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigCassandraTests.java deleted file mode 100644 index 1b6960ec..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigCassandraTests.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.util.HashMap; -import java.util.Map; - -import com.datastax.oss.driver.api.core.CqlSession; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the cassandra secret backend. In case this test should fail - * because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigCassandraTests.TestApplication.class, - properties = { "spring.cloud.vault.cassandra.enabled=true", "spring.cloud.vault.cassandra.role=readonly", - "spring.data.cassandra.jmx-enabled=false", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigCassandraTests { - - private static final String CASSANDRA_HOST = "localhost"; - - private static final int CASSANDRA_PORT = 9042; - - private static final String CASSANDRA_USERNAME = "springvault"; - - private static final String CASSANDRA_PASSWORD = "springvault"; - - private static final String CREATE_USER_AND_GRANT_CQL = "CREATE USER '{{username}}' WITH PASSWORD '{{password}}' NOSUPERUSER;" - + "GRANT SELECT ON ALL KEYSPACES TO {{username}};"; - - @Value("${spring.data.cassandra.username}") - String username; - - @Value("${spring.data.cassandra.password}") - String password; - - @Autowired - CqlSession cqlSession; - - /** - * Initialize the cassandra secret backend. - */ - @BeforeClass - public static void beforeClass() { - - assumeTrue(CanConnect.to(new InetSocketAddress(CASSANDRA_HOST, CASSANDRA_PORT))); - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - if (!vaultRule.prepare().hasSecretBackend("cassandra")) { - vaultRule.prepare().mountSecret("cassandra"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - Map connection = new HashMap<>(); - connection.put("hosts", CASSANDRA_HOST); - connection.put("username", CASSANDRA_USERNAME); - connection.put("password", CASSANDRA_PASSWORD); - connection.put("protocol_version", 3); - - vaultOperations.write(String.format("%s/config/connection", "cassandra"), connection); - - Map role = new HashMap<>(); - - role.put("creation_cql", CREATE_USER_AND_GRANT_CQL); - role.put("consistency", "All"); - - vaultOperations.write("cassandra/roles/readonly", role); - } - - @Test - public void shouldUseAuthenticatedSession() { - assertThat(this.cqlSession.getMetadata().getKeyspace("system")).isNotEmpty(); - } - - @Test - public void shouldConnectUsingCassandraClient() { - - try (CqlSession session = CqlSession.builder().withLocalDatacenter("dc1") - .addContactPoint(new InetSocketAddress(CASSANDRA_HOST, CASSANDRA_PORT)) - .withAuthCredentials(this.username, this.password).build()) { - assertThat(session.getMetadata().getKeyspace("system")).isNotEmpty(); - } - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigCouchbaseDatabaseTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigCouchbaseDatabaseTests.java deleted file mode 100644 index 690152b2..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigCouchbaseDatabaseTests.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; - -import com.couchbase.client.java.Cluster; -import com.couchbase.client.core.error.UnambiguousTimeoutException; - -import java.util.HashMap; -import java.util.Map; -import java.time.Duration; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the database secret backend. In case this test should fail - * because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Francis Hitchens - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigCouchbaseDatabaseTests.TestApplication.class, - properties = { "spring.cloud.vault.couchbase.enabled=true", "spring.config.import=vault://", - "spring.cloud.vault.couchbase.role=couchbase-readonly", - "spring.main.allow-bean-definition-overriding=true" }) -public class VaultConfigCouchbaseDatabaseTests { - - private static final int COUCHBASE_PORT = 8091; - - private static final String COUCHBASE_HOST = "localhost"; - - @Value("${spring.couchbase.username}") - String username; - - @Value("${spring.couchbase.password}") - String password; - - Cluster cluster; - - /** - * Initialize the couchbase secret backend. - */ - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - assumeTrue(CanConnect.to(new InetSocketAddress(COUCHBASE_HOST, COUCHBASE_PORT))); - assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("1.3.0"))); - - if (!vaultRule.prepare().hasSecretBackend("database")) { - vaultRule.prepare().mountSecret("database"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - Map config = new HashMap<>(); - config.put("plugin_name", "couchbase-database-plugin"); - config.put("hosts", "couchbase://localhost"); - config.put("username", "Administrator"); - config.put("password", "password"); - config.put("allowed_roles", "*"); - - vaultOperations.write("database/config/spring-cloud-vault-couchbase", config); - - Map body = new HashMap<>(); - body.put("db_name", "spring-cloud-vault-couchbase"); - body.put("creation_statements", "{\"roles\":[{\"role\":\"ro_admin\"}]}"); - - vaultOperations.write("database/roles/couchbase-readonly", body); - } - - @Test - public void shouldConnectConnection() throws UnambiguousTimeoutException { - - this.cluster = Cluster.connect("127.0.0.1", this.username, this.password); - this.cluster.waitUntilReady(Duration.ofSeconds(5)); - this.cluster.disconnect(); - } - - @Test(expected = UnambiguousTimeoutException.class) - public void shouldFailConnectConnection() throws UnambiguousTimeoutException { - - this.cluster = Cluster.connect("127.0.0.1", this.username, "fake.pwd"); - this.cluster.waitUntilReady(Duration.ofSeconds(5)); - this.cluster.disconnect(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigCouchbaseTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigCouchbaseTests.java deleted file mode 100644 index 994315dc..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigCouchbaseTests.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.util.HashMap; -import java.util.Map; - -import com.couchbase.client.java.Cluster; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the couchbase secret backend. In case this test should fail - * because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigCouchbaseTests.TestApplication.class, - properties = { "spring.cloud.vault.couchbase.enabled=true", "spring.config.import=vault://", - "spring.cloud.vault.couchbase.role=couchbase-readonly", - "spring.couchbase.connection-string=couchbase://localhost" }) -public class VaultConfigCouchbaseTests { - - private static final int COUCHBASE_PORT = 8091; - - private static final String COUCHBASE_HOST = "localhost"; - - @Value("${spring.couchbase.username}") - String username; - - @Value("${spring.couchbase.password}") - String password; - - @Autowired - Cluster cluster; - - /** - * Initialize the couchbase secret backend. - */ - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - assumeTrue(CanConnect.to(new InetSocketAddress(COUCHBASE_HOST, COUCHBASE_PORT))); - assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("1.3.0"))); - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - if (!vaultRule.prepare().hasSecretBackend("database")) { - vaultRule.prepare().mountSecret("database"); - } - - Map config = new HashMap<>(); - config.put("plugin_name", "couchbase-database-plugin"); - config.put("hosts", "couchbase://localhost"); - config.put("username", "Administrator"); - config.put("password", "password"); - config.put("allowed_roles", "*"); - - vaultOperations.write("database/config/spring-cloud-vault-couchbase", config); - - Map body = new HashMap<>(); - body.put("db_name", "spring-cloud-vault-couchbase"); - body.put("creation_statements", "{\"roles\":[{\"role\":\"ro_admin\"}]}"); - - vaultOperations.write("database/roles/couchbase-readonly", body); - } - - @Test - public void shouldUseAuthenticatedSession() { - assertThat(this.cluster.buckets().getAllBuckets()).isNotEmpty(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfigurationTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfigurationTests.java deleted file mode 100644 index e223f50c..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfigurationTests.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Qualifier; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.config.KeyValueSecretBackendMetadata; -import org.springframework.cloud.vault.config.SecretBackendMetadata; -import org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory; -import org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfigurationTests.CustomBootstrapConfiguration; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link VaultConfigDatabaseBootstrapConfiguration}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = CustomBootstrapConfiguration.class, - properties = { "VaultConfigDatabaseBootstrapConfigurationTests.custom.config=true", - "spring.cloud.vault.mysql.role=foo", "spring.cloud.vault.mysql.enabled=true", - "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigDatabaseBootstrapConfigurationTests extends IntegrationTestSupport { - - @Autowired - @Qualifier("customFactory") - DatabaseSecretBackendMetadataFactory factory; - - @SuppressWarnings("deprecation") - @Autowired - VaultMySqlProperties properties; - - @Test - public void shouldApplyCustomConfiguration() { - - SecretBackendMetadata metadata = this.factory.createMetadata(this.properties); - - assertThat(metadata).isInstanceOf(KeyValueSecretBackendMetadata.class); - assertThat(metadata.getPath()).isEqualTo(this.properties.getRole()); - } - - @Configuration(proxyBeanMethods = false) - public static class CustomBootstrapConfiguration { - - @Bean - @ConditionalOnProperty("VaultConfigDatabaseBootstrapConfigurationTests.custom.config") - DatabaseSecretBackendMetadataFactory customFactory() { - - return new DatabaseSecretBackendMetadataFactory() { - @Override - public SecretBackendMetadata createMetadata(DatabaseSecretProperties backendDescriptor) { - return KeyValueSecretBackendMetadata.create(backendDescriptor.getRole()); - } - }; - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfigurationUnitTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfigurationUnitTests.java deleted file mode 100644 index 6379cd0b..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigDatabaseBootstrapConfigurationUnitTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import org.junit.Test; - -import org.springframework.cloud.vault.config.SecretBackendMetadata; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link VaultConfigDatabaseBootstrapConfiguration}. - * - * @author Mark Paluch - */ -public class VaultConfigDatabaseBootstrapConfigurationUnitTests { - - @Test - public void shouldConsiderCredentialPath() { - - VaultConfigDatabaseBootstrapConfiguration.DatabaseSecretBackendMetadataFactory factory = new VaultConfigDatabaseBootstrapConfiguration() - .databaseSecretBackendMetadataFactory(); - - VaultDatabaseProperties properties = new VaultDatabaseProperties(); - properties.setStaticRole(true); - properties.setRole("my-role"); - - SecretBackendMetadata metadata = factory.createMetadata(properties); - - assertThat(metadata.getPath()).isEqualTo("database/static-creds/my-role"); - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMongoTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMongoTests.java deleted file mode 100644 index 78e36f4b..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMongoTests.java +++ /dev/null @@ -1,132 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.util.ArrayList; -import java.util.Collections; -import java.util.HashMap; -import java.util.List; -import java.util.Map; - -import com.mongodb.client.MongoClient; -import com.mongodb.client.MongoDatabase; -import org.bson.Document; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the mongodb secret backend. In case this test should fail - * because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigMongoTests.TestApplication.class, - properties = { "spring.cloud.vault.mongodb.enabled=true", "spring.cloud.vault.mongodb.role=readonly", - "spring.data.mongodb.url=mongodb://localhost", "spring.data.mongodb.database=admin", - "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigMongoTests { - - private static final int MONGODB_PORT = 27017; - - private static final String MONGODB_HOST = "localhost"; - - private static final String ROOT_CREDENTIALS = String - .format("mongodb://springvault:springvault@%s:%d/admin?ssl=false", MONGODB_HOST, MONGODB_PORT); - - private static final String ROLES = "[ \"readWrite\", { \"role\": \"read\", \"db\": \"admin\" } ]"; - - @Value("${spring.data.mongodb.username}") - String username; - - @Value("${spring.data.mongodb.password}") - String password; - - @Autowired - MongoClient mongoClient; - - /** - * Initialize the mongo secret backend. - */ - @BeforeClass - public static void beforeClass() { - - assumeTrue(CanConnect.to(new InetSocketAddress(MONGODB_HOST, MONGODB_PORT))); - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.2"))); - - if (!vaultRule.prepare().hasSecretBackend("mongodb")) { - vaultRule.prepare().mountSecret("mongodb"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - vaultOperations.write("mongodb/config/connection", Collections.singletonMap("uri", ROOT_CREDENTIALS)); - - Map role = new HashMap<>(); - role.put("db", "admin"); - role.put("roles", ROLES); - - vaultOperations.write("mongodb/roles/readonly", role); - } - - @Test - public void shouldConnectUsingDataSource() { - - MongoDatabase mongoDatabase = this.mongoClient.getDatabase("admin"); - - List collections = mongoDatabase.listCollections().into(new ArrayList<>()); - - for (Document collection : collections) { - if (collection.getString("name").equals("hello")) { - mongoDatabase.getCollection(collection.getString("name")).drop(); - } - } - - mongoDatabase.createCollection("hello"); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args).registerShutdownHook(); - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlDatabaseTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlDatabaseTests.java deleted file mode 100644 index 625ac84b..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlDatabaseTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.sql.DriverManager; -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the database secret backend. In case this test should fail - * because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigMySqlDatabaseTests.TestApplication.class, - properties = { "spring.cloud.vault.database.enabled=true", "spring.cloud.vault.database.role=readonly", - "spring.datasource.url=" + MySqlFixtures.JDBC_URL, "spring.main.allow-bean-definition-overriding=true", - "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigMySqlDatabaseTests { - - @Value("${spring.datasource.username}") - String username; - - @Value("${spring.datasource.password}") - String password; - - @Autowired - DataSource dataSource; - - /** - * Initialize the mysql secret backend. - */ - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - assumeTrue(CanConnect.to(new InetSocketAddress(MySqlFixtures.MYSQL_HOST, MySqlFixtures.MYSQL_PORT))); - assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.7.1"))); - - MySqlFixtures.setupMysql(vaultRule); - } - - @Test - public void shouldConnectUsingDataSource() throws SQLException { - this.dataSource.getConnection().close(); - } - - @Test - public void shouldConnectUsingJdbcUrlConnection() throws SQLException { - DriverManager.getConnection(MySqlFixtures.JDBC_URL, this.username, this.password).close(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlDatabasesBootstrapTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlDatabasesBootstrapTests.java deleted file mode 100644 index 0904974c..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlDatabasesBootstrapTests.java +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the database secret backend with multi-database support. In - * case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigMySqlDatabasesBootstrapTests.TestApplication.class, properties = { - "spring.cloud.vault.databases.mysql.enabled=true", "spring.cloud.vault.databases.mysql.role=readonly", - "spring.datasource.url=jdbc:mysql://localhost:3306/mysql?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true", - "spring.main.allow-bean-definition-overriding=true", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigMySqlDatabasesBootstrapTests { - - private static final int MYSQL_PORT = 3306; - - private static final String MYSQL_HOST = "localhost"; - - private static final String ROOT_CREDENTIALS = String.format("root:springvault@tcp(%s:%d)/", MYSQL_HOST, - MYSQL_PORT); - - private static final String CREATE_USER_AND_GRANT_SQL = "CREATE USER '{{name}}'@'%' IDENTIFIED BY '{{password}}';" - + "GRANT SELECT ON *.* TO '{{name}}'@'%';"; - - @Value("${spring.datasource.username}") - String username; - - @Value("${spring.datasource.password}") - String password; - - @Autowired - DataSource dataSource; - - /** - * Initialize the mysql secret backend. - */ - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - assumeTrue(CanConnect.to(new InetSocketAddress(MYSQL_HOST, MYSQL_PORT))); - assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.7.1"))); - - if (!vaultRule.prepare().hasSecretBackend("database")) { - vaultRule.prepare().mountSecret("database"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - Map config = new HashMap<>(); - config.put("plugin_name", "mysql-legacy-database-plugin"); - config.put("connection_url", ROOT_CREDENTIALS); - config.put("allowed_roles", "readonly"); - - vaultOperations.write("database/config/mysql", config); - - Map body = new HashMap<>(); - body.put("db_name", "mysql"); - body.put("creation_statements", CREATE_USER_AND_GRANT_SQL); - - vaultOperations.write("database/roles/readonly", body); - } - - @Test - public void shouldConnectUsingDataSource() throws SQLException { - - this.dataSource.getConnection().close(); - } - - @Test - public void shouldConnectUsingJdbcUrlConnection() throws SQLException { - - String url = String.format("jdbc:mysql://%s?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true", - MYSQL_HOST); - DriverManager.getConnection(url, this.username, this.password).close(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlDatabasesTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlDatabasesTests.java deleted file mode 100644 index 909702cf..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlDatabasesTests.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.sql.DriverManager; -import java.sql.SQLException; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the database secret backend with multi-database support. In - * case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigMySqlDatabasesTests.TestApplication.class, - properties = { "spring.cloud.vault.databases.mysql.enabled=true", - "spring.cloud.vault.databases.mysql.role=readonly", "spring.datasource.url=" + MySqlFixtures.JDBC_URL, - "spring.config.import=vault://" }) -public class VaultConfigMySqlDatabasesTests { - - @Value("${spring.datasource.username}") - String username; - - @Value("${spring.datasource.password}") - String password; - - @Autowired - DataSource dataSource; - - /** - * Initialize the mysql secret backend. - */ - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - assumeTrue(CanConnect.to(new InetSocketAddress(MySqlFixtures.MYSQL_HOST, MySqlFixtures.MYSQL_PORT))); - assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.7.1"))); - - MySqlFixtures.setupMysql(vaultRule); - } - - @Test - public void shouldConnectUsingDataSource() throws SQLException { - - this.dataSource.getConnection().close(); - } - - @Test - public void shouldConnectUsingJdbcUrlConnection() throws SQLException { - DriverManager.getConnection(MySqlFixtures.JDBC_URL, this.username, this.password).close(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlTests.java deleted file mode 100644 index b1f9f457..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigMySqlTests.java +++ /dev/null @@ -1,109 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Collections; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the mysql secret backend. In case this test should fail because - * of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigMySqlTests.TestApplication.class, - properties = { "spring.cloud.vault.mysql.enabled=true", "spring.cloud.vault.mysql.role=readonly", - "spring.datasource.url=" + MySqlFixtures.JDBC_URL, "spring.main.allow-bean-definition-overriding=true", - "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigMySqlTests { - - @Value("${spring.datasource.username}") - String username; - - @Value("${spring.datasource.password}") - String password; - - @Autowired - DataSource dataSource; - - /** - * Initialize the mysql secret backend. - */ - @BeforeClass - public static void beforeClass() { - - assumeTrue(CanConnect.to(new InetSocketAddress(MySqlFixtures.MYSQL_HOST, MySqlFixtures.MYSQL_PORT))); - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - if (!vaultRule.prepare().hasSecretBackend("mysql")) { - vaultRule.prepare().mountSecret("mysql"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - vaultOperations.write("mysql/config/connection", - Collections.singletonMap("connection_url", MySqlFixtures.ROOT_CREDENTIALS)); - - vaultOperations.write("mysql/roles/readonly", - Collections.singletonMap("sql", MySqlFixtures.CREATE_USER_AND_GRANT_SQL)); - } - - @Test - public void shouldConnectUsingDataSource() throws SQLException { - this.dataSource.getConnection().close(); - } - - @Test - public void shouldConnectUsingJdbcUrlConnection() throws SQLException { - DriverManager.getConnection(MySqlFixtures.JDBC_URL, this.username, this.password).close(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigPostgreSqlTests.java b/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigPostgreSqlTests.java deleted file mode 100644 index 9bd00e0f..00000000 --- a/spring-cloud-vault-config-databases/src/test/java/org/springframework/cloud/vault/config/databases/VaultConfigPostgreSqlTests.java +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.databases; - -import java.net.InetSocketAddress; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.SQLException; -import java.util.Collections; - -import javax.sql.DataSource; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the postgresql secret backend. In case this test should fail - * because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigPostgreSqlTests.TestApplication.class, - properties = { "spring.cloud.vault.postgresql.enabled=true", "spring.cloud.vault.postgresql.role=readonly", - "spring.datasource.url=jdbc:postgresql://localhost:5432/postgres?ssl=false", - "spring.main.allow-bean-definition-overriding=true", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigPostgreSqlTests { - - private static final String POSTGRES_HOST = "localhost"; - - private static final int POSTGRES_PORT = 5432; - - private static final String CONNECTION_URL = String.format( - "postgresql://springvault:springvault@%s:%d/postgres?sslmode=disable", POSTGRES_HOST, POSTGRES_PORT); - - private static final String CREATE_USER_AND_GRANT_SQL = "CREATE ROLE \"{{name}}\" WITH " - + "LOGIN PASSWORD '{{password}}' VALID UNTIL '{{expiration}}';\n" - + "GRANT SELECT ON ALL TABLES IN SCHEMA public TO \"{{name}}\";"; - - @Value("${spring.datasource.username}") - String username; - - @Value("${spring.datasource.password}") - String password; - - @Autowired - DataSource dataSource; - - /** - * Initialize the postgresql secret backend. - */ - @BeforeClass - public static void beforeClass() { - - assumeTrue(CanConnect.to(new InetSocketAddress(POSTGRES_HOST, POSTGRES_PORT))); - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - if (!vaultRule.prepare().hasSecretBackend("postgresql")) { - vaultRule.prepare().mountSecret("postgresql"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - vaultOperations.write("postgresql/config/connection", - Collections.singletonMap("connection_url", CONNECTION_URL)); - - vaultOperations.write("postgresql/roles/readonly", Collections.singletonMap("sql", CREATE_USER_AND_GRANT_SQL)); - } - - @Test - public void shouldConnectUsingDataSource() throws SQLException { - - Connection connection = this.dataSource.getConnection(); - - assertThat(connection.getSchema()).isEqualTo("public"); - connection.close(); - } - - @Test - public void shouldConnectUsingJdbcUrlConnection() throws SQLException { - - String url = String.format("jdbc:postgresql://%s:%d/postgres?ssl=false", POSTGRES_HOST, POSTGRES_PORT); - DriverManager.getConnection(url, this.username, this.password).close(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-databases/src/test/resources/META-INF/spring.factories b/spring-cloud-vault-config-databases/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 1a44208a..00000000 --- a/spring-cloud-vault-config-databases/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,4 +0,0 @@ -# Bootstrap Configuration -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfigurationTests.CustomBootstrapConfiguration,\ -org.springframework.cloud.vault.config.databases.VaultConfigDatabaseBootstrapConfiguration diff --git a/spring-cloud-vault-config-databases/src/test/resources/bootstrap.yml b/spring-cloud-vault-config-databases/src/test/resources/bootstrap.yml deleted file mode 100644 index c598d962..00000000 --- a/spring-cloud-vault-config-databases/src/test/resources/bootstrap.yml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - application.name: testVaultApp - cloud.vault.token: 00000000-0000-0000-0000-000000000000 - cloud.vault.ssl.trust-store: file:../work/keystore.jks - cloud.vault.ssl.trust-store-password: changeit diff --git a/spring-cloud-vault-config-databases/src/test/resources/cassandra.yaml b/spring-cloud-vault-config-databases/src/test/resources/cassandra.yaml deleted file mode 100644 index 6598e513..00000000 --- a/spring-cloud-vault-config-databases/src/test/resources/cassandra.yaml +++ /dev/null @@ -1,1239 +0,0 @@ -# Cassandra storage config YAML - -# NOTE: -# See https://wiki.apache.org/cassandra/StorageConfiguration for -# full explanations of configuration directives -# /NOTE - -# The name of the cluster. This is mainly used to prevent machines in -# one logical cluster from joining another. -cluster_name: 'Test Cluster' - -# This defines the number of tokens randomly assigned to this node on the ring -# The more tokens, relative to other nodes, the larger the proportion of data -# that this node will store. You probably want all nodes to have the same number -# of tokens assuming they have equal hardware capability. -# -# If you leave this unspecified, Cassandra will use the default of 1 token for legacy compatibility, -# and will use the initial_token as described below. -# -# Specifying initial_token will override this setting on the node's initial start, -# on subsequent starts, this setting will apply even if initial token is set. -# -# If you already have a cluster with 1 token per node, and wish to migrate to -# multiple tokens per node, see https://wiki.apache.org/cassandra/Operations -num_tokens: 256 - -# Triggers automatic allocation of num_tokens tokens for this node. The allocation -# algorithm attempts to choose tokens in a way that optimizes replicated load over -# the nodes in the datacenter for the replication strategy used by the specified -# keyspace. -# -# The load assigned to each node will be close to proportional to its number of -# vnodes. -# -# Only supported with the Murmur3Partitioner. -# allocate_tokens_for_keyspace: KEYSPACE - -# initial_token allows you to specify tokens manually. While you can use it with -# vnodes (num_tokens > 1, above) -- in which case you should provide a -# comma-separated list -- it's primarily used when adding nodes to legacy clusters -# that do not have vnodes enabled. -# initial_token: - -# See https://wiki.apache.org/cassandra/HintedHandoff -# May either be "true" or "false" to enable globally -hinted_handoff_enabled: true - -# When hinted_handoff_enabled is true, a black list of data centers that will not -# perform hinted handoff -# hinted_handoff_disabled_datacenters: -# - DC1 -# - DC2 - -# this defines the maximum amount of time a dead host will have hints -# generated. After it has been dead this long, new hints for it will not be -# created until it has been seen alive and gone down again. -max_hint_window_in_ms: 10800000 # 3 hours - -# Maximum throttle in KBs per second, per delivery thread. This will be -# reduced proportionally to the number of nodes in the cluster. (If there -# are two nodes in the cluster, each delivery thread will use the maximum -# rate; if there are three, each will throttle to half of the maximum, -# since we expect two nodes to be delivering hints simultaneously.) -hinted_handoff_throttle_in_kb: 1024 - -# Number of threads with which to deliver hints; -# Consider increasing this number when you have multi-dc deployments, since -# cross-dc handoff tends to be slower -max_hints_delivery_threads: 2 - -# Directory where Cassandra should store hints. -# If not set, the default directory is $CASSANDRA_HOME/data/hints. -# hints_directory: /var/lib/cassandra/hints - -# How often hints should be flushed from the internal buffers to disk. -# Will *not* trigger fsync. -hints_flush_period_in_ms: 10000 - -# Maximum size for a single hints file, in megabytes. -max_hints_file_size_in_mb: 128 - -# Compression to apply to the hint files. If omitted, hints files -# will be written uncompressed. LZ4, Snappy, and Deflate compressors -# are supported. -#hints_compression: -# - class_name: LZ4Compressor -# parameters: -# - - -# Maximum throttle in KBs per second, total. This will be -# reduced proportionally to the number of nodes in the cluster. -batchlog_replay_throttle_in_kb: 1024 - -# Authentication backend, implementing IAuthenticator; used to identify users -# Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllAuthenticator, -# PasswordAuthenticator}. -# -# - AllowAllAuthenticator performs no checks - set it to disable authentication. -# - PasswordAuthenticator relies on username/password pairs to authenticate -# users. It keeps usernames and hashed passwords in system_auth.roles table. -# Please increase system_auth keyspace replication factor if you use this authenticator. -# If using PasswordAuthenticator, CassandraRoleManager must also be used (see below) -#authenticator: PasswordAuthenticator -authenticator: PasswordAuthenticator - -# Authorization backend, implementing IAuthorizer; used to limit access/provide permissions -# Out of the box, Cassandra provides org.apache.cassandra.auth.{AllowAllAuthorizer, -# CassandraAuthorizer}. -# -# - AllowAllAuthorizer allows any action to any user - set it to disable authorization. -# - CassandraAuthorizer stores permissions in system_auth.role_permissions table. Please -# increase system_auth keyspace replication factor if you use this authorizer. -#authorizer: CassandraAuthorizer -authorizer: CassandraAuthorizer - -# Part of the Authentication & Authorization backend, implementing IRoleManager; used -# to maintain grants and memberships between roles. -# Out of the box, Cassandra provides org.apache.cassandra.auth.CassandraRoleManager, -# which stores role information in the system_auth keyspace. Most functions of the -# IRoleManager require an authenticated login, so unless the configured IAuthenticator -# actually implements authentication, most of this functionality will be unavailable. -# -# - CassandraRoleManager stores role data in the system_auth keyspace. Please -# increase system_auth keyspace replication factor if you use this role manager. -role_manager: CassandraRoleManager - -# Validity period for roles cache (fetching granted roles can be an expensive -# operation depending on the role manager, CassandraRoleManager is one example) -# Granted roles are cached for authenticated sessions in AuthenticatedUser and -# after the period specified here, become eligible for (async) reload. -# Defaults to 2000, set to 0 to disable caching entirely. -# Will be disabled automatically for AllowAllAuthenticator. -roles_validity_in_ms: 2000 - -# Refresh interval for roles cache (if enabled). -# After this interval, cache entries become eligible for refresh. Upon next -# access, an async reload is scheduled and the old value returned until it -# completes. If roles_validity_in_ms is non-zero, then this must be -# also. -# Defaults to the same value as roles_validity_in_ms. -# roles_update_interval_in_ms: 2000 - -# Validity period for permissions cache (fetching permissions can be an -# expensive operation depending on the authorizer, CassandraAuthorizer is -# one example). Defaults to 2000, set to 0 to disable. -# Will be disabled automatically for AllowAllAuthorizer. -permissions_validity_in_ms: 2000 - -# Refresh interval for permissions cache (if enabled). -# After this interval, cache entries become eligible for refresh. Upon next -# access, an async reload is scheduled and the old value returned until it -# completes. If permissions_validity_in_ms is non-zero, then this must be -# also. -# Defaults to the same value as permissions_validity_in_ms. -# permissions_update_interval_in_ms: 2000 - -# Validity period for credentials cache. This cache is tightly coupled to -# the provided PasswordAuthenticator implementation of IAuthenticator. If -# another IAuthenticator implementation is configured, this cache will not -# be automatically used and so the following settings will have no effect. -# Please note, credentials are cached in their encrypted form, so while -# activating this cache may reduce the number of queries made to the -# underlying table, it may not bring a significant reduction in the -# latency of individual authentication attempts. -# Defaults to 2000, set to 0 to disable credentials caching. -credentials_validity_in_ms: 2000 - -# Refresh interval for credentials cache (if enabled). -# After this interval, cache entries become eligible for refresh. Upon next -# access, an async reload is scheduled and the old value returned until it -# completes. If credentials_validity_in_ms is non-zero, then this must be -# also. -# Defaults to the same value as credentials_validity_in_ms. -# credentials_update_interval_in_ms: 2000 - -# The partitioner is responsible for distributing groups of rows (by -# partition key) across nodes in the cluster. You should leave this -# alone for new clusters. The partitioner can NOT be changed without -# reloading all data, so when upgrading you should set this to the -# same partitioner you were already using. -# -# Besides Murmur3Partitioner, partitioners included for backwards -# compatibility include RandomPartitioner, ByteOrderedPartitioner, and -# OrderPreservingPartitioner. -# -partitioner: org.apache.cassandra.dht.Murmur3Partitioner - -# Directories where Cassandra should store data on disk. Cassandra -# will spread data evenly across them, subject to the granularity of -# the configured compaction strategy. -# If not set, the default directory is $CASSANDRA_HOME/data/data. -# data_file_directories: -# - /var/lib/cassandra/data - -# commit log. when running on magnetic HDD, this should be a -# separate spindle than the data directories. -# If not set, the default directory is $CASSANDRA_HOME/data/commitlog. -# commitlog_directory: /var/lib/cassandra/commitlog - -# Enable / disable CDC functionality on a per-node basis. This modifies the logic used -# for write path allocation rejection (standard: never reject. cdc: reject Mutation -# containing a CDC-enabled table if at space limit in cdc_raw_directory). -cdc_enabled: false - -# CommitLogSegments are moved to this directory on flush if cdc_enabled: true and the -# segment contains mutations for a CDC-enabled table. This should be placed on a -# separate spindle than the data directories. If not set, the default directory is -# $CASSANDRA_HOME/data/cdc_raw. -# cdc_raw_directory: /var/lib/cassandra/cdc_raw - -# Policy for data disk failures: -# -# die -# shut down gossip and client transports and kill the JVM for any fs errors or -# single-sstable errors, so the node can be replaced. -# -# stop_paranoid -# shut down gossip and client transports even for single-sstable errors, -# kill the JVM for errors during startup. -# -# stop -# shut down gossip and client transports, leaving the node effectively dead, but -# can still be inspected via JMX, kill the JVM for errors during startup. -# -# best_effort -# stop using the failed disk and respond to requests based on -# remaining available sstables. This means you WILL see obsolete -# data at CL.ONE! -# -# ignore -# ignore fatal errors and let requests fail, as in pre-1.2 Cassandra -disk_failure_policy: stop - -# Policy for commit disk failures: -# -# die -# shut down gossip and Thrift and kill the JVM, so the node can be replaced. -# -# stop -# shut down gossip and Thrift, leaving the node effectively dead, but -# can still be inspected via JMX. -# -# stop_commit -# shutdown the commit log, letting writes collect but -# continuing to service reads, as in pre-2.0.5 Cassandra -# -# ignore -# ignore fatal errors and let the batches fail -commit_failure_policy: stop - -# Maximum size of the native protocol prepared statement cache -# -# Valid values are either "auto" (omitting the value) or a value greater 0. -# -# Note that specifying a too large value will result in long running GCs and possbily -# out-of-memory errors. Keep the value at a small fraction of the heap. -# -# If you constantly see "prepared statements discarded in the last minute because -# cache limit reached" messages, the first step is to investigate the root cause -# of these messages and check whether prepared statements are used correctly - -# i.e. use bind markers for variable parts. -# -# Do only change the default value, if you really have more prepared statements than -# fit in the cache. In most cases it is not neccessary to change this value. -# Constantly re-preparing statements is a performance penalty. -# -# Default value ("auto") is 1/256th of the heap or 10MB, whichever is greater -prepared_statements_cache_size_mb: - -# Maximum size of the Thrift prepared statement cache -# -# If you do not use Thrift at all, it is safe to leave this value at "auto". -# -# See description of 'prepared_statements_cache_size_mb' above for more information. -# -# Default value ("auto") is 1/256th of the heap or 10MB, whichever is greater -thrift_prepared_statements_cache_size_mb: - -# Maximum size of the key cache in memory. -# -# Each key cache hit saves 1 seek and each row cache hit saves 2 seeks at the -# minimum, sometimes more. The key cache is fairly tiny for the amount of -# time it saves, so it's worthwhile to use it at large numbers. -# The row cache saves even more time, but must contain the entire row, -# so it is extremely space-intensive. It's best to only use the -# row cache if you have hot rows or static rows. -# -# NOTE: if you reduce the size, you may not get you hottest keys loaded on startup. -# -# Default value is empty to make it "auto" (min(5% of Heap (in MB), 100MB)). Set to 0 to disable key cache. -key_cache_size_in_mb: - -# Duration in seconds after which Cassandra should -# save the key cache. Caches are saved to saved_caches_directory as -# specified in this configuration file. -# -# Saved caches greatly improve cold-start speeds, and is relatively cheap in -# terms of I/O for the key cache. Row cache saving is much more expensive and -# has limited use. -# -# Default is 14400 or 4 hours. -key_cache_save_period: 14400 - -# Number of keys from the key cache to save -# Disabled by default, meaning all keys are going to be saved -# key_cache_keys_to_save: 100 - -# Row cache implementation class name. Available implementations: -# -# org.apache.cassandra.cache.OHCProvider -# Fully off-heap row cache implementation (default). -# -# org.apache.cassandra.cache.SerializingCacheProvider -# This is the row cache implementation availabile -# in previous releases of Cassandra. -# row_cache_class_name: org.apache.cassandra.cache.OHCProvider - -# Maximum size of the row cache in memory. -# Please note that OHC cache implementation requires some additional off-heap memory to manage -# the map structures and some in-flight memory during operations before/after cache entries can be -# accounted against the cache capacity. This overhead is usually small compared to the whole capacity. -# Do not specify more memory that the system can afford in the worst usual situation and leave some -# headroom for OS block level cache. Do never allow your system to swap. -# -# Default value is 0, to disable row caching. -row_cache_size_in_mb: 0 - -# Duration in seconds after which Cassandra should save the row cache. -# Caches are saved to saved_caches_directory as specified in this configuration file. -# -# Saved caches greatly improve cold-start speeds, and is relatively cheap in -# terms of I/O for the key cache. Row cache saving is much more expensive and -# has limited use. -# -# Default is 0 to disable saving the row cache. -row_cache_save_period: 0 - -# Number of keys from the row cache to save. -# Specify 0 (which is the default), meaning all keys are going to be saved -# row_cache_keys_to_save: 100 - -# Maximum size of the counter cache in memory. -# -# Counter cache helps to reduce counter locks' contention for hot counter cells. -# In case of RF = 1 a counter cache hit will cause Cassandra to skip the read before -# write entirely. With RF > 1 a counter cache hit will still help to reduce the duration -# of the lock hold, helping with hot counter cell updates, but will not allow skipping -# the read entirely. Only the local (clock, count) tuple of a counter cell is kept -# in memory, not the whole counter, so it's relatively cheap. -# -# NOTE: if you reduce the size, you may not get you hottest keys loaded on startup. -# -# Default value is empty to make it "auto" (min(2.5% of Heap (in MB), 50MB)). Set to 0 to disable counter cache. -# NOTE: if you perform counter deletes and rely on low gcgs, you should disable the counter cache. -counter_cache_size_in_mb: - -# Duration in seconds after which Cassandra should -# save the counter cache (keys only). Caches are saved to saved_caches_directory as -# specified in this configuration file. -# -# Default is 7200 or 2 hours. -counter_cache_save_period: 7200 - -# Number of keys from the counter cache to save -# Disabled by default, meaning all keys are going to be saved -# counter_cache_keys_to_save: 100 - -# saved caches -# If not set, the default directory is $CASSANDRA_HOME/data/saved_caches. -# saved_caches_directory: /var/lib/cassandra/saved_caches - -# commitlog_sync may be either "periodic" or "batch." -# -# When in batch mode, Cassandra won't ack writes until the commit log -# has been fsynced to disk. It will wait -# commitlog_sync_batch_window_in_ms milliseconds between fsyncs. -# This window should be kept short because the writer threads will -# be unable to do extra work while waiting. (You may need to increase -# concurrent_writes for the same reason.) -# -# commitlog_sync: batch -# commitlog_sync_batch_window_in_ms: 2 -# -# the other option is "periodic" where writes may be acked immediately -# and the CommitLog is simply synced every commitlog_sync_period_in_ms -# milliseconds. -commitlog_sync: periodic -commitlog_sync_period_in_ms: 10000 - -# The size of the individual commitlog file segments. A commitlog -# segment may be archived, deleted, or recycled once all the data -# in it (potentially from each columnfamily in the system) has been -# flushed to sstables. -# -# The default size is 32, which is almost always fine, but if you are -# archiving commitlog segments (see commitlog_archiving.properties), -# then you probably want a finer granularity of archiving; 8 or 16 MB -# is reasonable. -# Max mutation size is also configurable via max_mutation_size_in_kb setting in -# cassandra.yaml. The default is half the size commitlog_segment_size_in_mb * 1024. -# This should be positive and less than 2048. -# -# NOTE: If max_mutation_size_in_kb is set explicitly then commitlog_segment_size_in_mb must -# be set to at least twice the size of max_mutation_size_in_kb / 1024 -# -commitlog_segment_size_in_mb: 32 - -# Compression to apply to the commit log. If omitted, the commit log -# will be written uncompressed. LZ4, Snappy, and Deflate compressors -# are supported. -# commitlog_compression: -# - class_name: LZ4Compressor -# parameters: -# - - -# any class that implements the SeedProvider interface and has a -# constructor that takes a Map of parameters will do. -seed_provider: - # Addresses of hosts that are deemed contact points. - # Cassandra nodes use this list of hosts to find each other and learn - # the topology of the ring. You must change this if you are running - # multiple nodes! - - class_name: org.apache.cassandra.locator.SimpleSeedProvider - parameters: - # seeds is actually a comma-delimited list of addresses. - # Ex: ",," - - seeds: "127.0.0.1" - -# For workloads with more data than can fit in memory, Cassandra's -# bottleneck will be reads that need to fetch data from -# disk. "concurrent_reads" should be set to (16 * number_of_drives) in -# order to allow the operations to enqueue low enough in the stack -# that the OS and drives can reorder them. Same applies to -# "concurrent_counter_writes", since counter writes read the current -# values before incrementing and writing them back. -# -# On the other hand, since writes are almost never IO bound, the ideal -# number of "concurrent_writes" is dependent on the number of cores in -# your system; (8 * number_of_cores) is a good rule of thumb. -concurrent_reads: 32 -concurrent_writes: 32 -concurrent_counter_writes: 32 - -# For materialized view writes, as there is a read involved, so this should -# be limited by the less of concurrent reads or concurrent writes. -concurrent_materialized_view_writes: 32 - -# Maximum memory to use for sstable chunk cache and buffer pooling. -# 32MB of this are reserved for pooling buffers, the rest is used as an -# cache that holds uncompressed sstable chunks. -# Defaults to the smaller of 1/4 of heap or 512MB. This pool is allocated off-heap, -# so is in addition to the memory allocated for heap. The cache also has on-heap -# overhead which is roughly 128 bytes per chunk (i.e. 0.2% of the reserved size -# if the default 64k chunk size is used). -# Memory is only allocated when needed. -# file_cache_size_in_mb: 512 - -# Flag indicating whether to allocate on or off heap when the sstable buffer -# pool is exhausted, that is when it has exceeded the maximum memory -# file_cache_size_in_mb, beyond which it will not cache buffers but allocate on request. - -# buffer_pool_use_heap_if_exhausted: true - -# The strategy for optimizing disk read -# Possible values are: -# ssd (for solid state disks, the default) -# spinning (for spinning disks) -# disk_optimization_strategy: ssd - -# Total permitted memory to use for memtables. Cassandra will stop -# accepting writes when the limit is exceeded until a flush completes, -# and will trigger a flush based on memtable_cleanup_threshold -# If omitted, Cassandra will set both to 1/4 the size of the heap. -# memtable_heap_space_in_mb: 2048 -# memtable_offheap_space_in_mb: 2048 - -# memtable_cleanup_threshold is deprecated. The default calculation -# is the only reasonable choice. See the comments on memtable_flush_writers -# for more information. -# -# Ratio of occupied non-flushing memtable size to total permitted size -# that will trigger a flush of the largest memtable. Larger mct will -# mean larger flushes and hence less compaction, but also less concurrent -# flush activity which can make it difficult to keep your disks fed -# under heavy write load. -# -# memtable_cleanup_threshold defaults to 1 / (memtable_flush_writers + 1) -# memtable_cleanup_threshold: 0.11 - -# Specify the way Cassandra allocates and manages memtable memory. -# Options are: -# -# heap_buffers -# on heap nio buffers -# -# offheap_buffers -# off heap (direct) nio buffers -# -# offheap_objects -# off heap objects -memtable_allocation_type: heap_buffers - -# Total space to use for commit logs on disk. -# -# If space gets above this value, Cassandra will flush every dirty CF -# in the oldest segment and remove it. So a small total commitlog space -# will tend to cause more flush activity on less-active columnfamilies. -# -# The default value is the smaller of 8192, and 1/4 of the total space -# of the commitlog volume. -# -# commitlog_total_space_in_mb: 8192 - -# This sets the number of memtable flush writer threads per disk -# as well as the total number of memtables that can be flushed concurrently. -# These are generally a combination of compute and IO bound. -# -# Memtable flushing is more CPU efficient than memtable ingest and a single thread -# can keep up with the ingest rate of a whole server on a single fast disk -# until it temporarily becomes IO bound under contention typically with compaction. -# At that point you need multiple flush threads. At some point in the future -# it may become CPU bound all the time. -# -# You can tell if flushing is falling behind using the MemtablePool.BlockedOnAllocation -# metric which should be 0, but will be non-zero if threads are blocked waiting on flushing -# to free memory. -# -# memtable_flush_writers defaults to two for a single data directory. -# This means that two memtables can be flushed concurrently to the single data directory. -# If you have multiple data directories the default is one memtable flushing at a time -# but the flush will use a thread per data directory so you will get two or more writers. -# -# Two is generally enough to flush on a fast disk [array] mounted as a single data directory. -# Adding more flush writers will result in smaller more frequent flushes that introduce more -# compaction overhead. -# -# There is a direct tradeoff between number of memtables that can be flushed concurrently -# and flush size and frequency. More is not better you just need enough flush writers -# to never stall waiting for flushing to free memory. -# -#memtable_flush_writers: 2 - -# Total space to use for change-data-capture logs on disk. -# -# If space gets above this value, Cassandra will throw WriteTimeoutException -# on Mutations including tables with CDC enabled. A CDCCompactor is responsible -# for parsing the raw CDC logs and deleting them when parsing is completed. -# -# The default value is the min of 4096 mb and 1/8th of the total space -# of the drive where cdc_raw_directory resides. -# cdc_total_space_in_mb: 4096 - -# When we hit our cdc_raw limit and the CDCCompactor is either running behind -# or experiencing backpressure, we check at the following interval to see if any -# new space for cdc-tracked tables has been made available. Default to 250ms -# cdc_free_space_check_interval_ms: 250 - -# A fixed memory pool size in MB for for SSTable index summaries. If left -# empty, this will default to 5% of the heap size. If the memory usage of -# all index summaries exceeds this limit, SSTables with low read rates will -# shrink their index summaries in order to meet this limit. However, this -# is a best-effort process. In extreme conditions Cassandra may need to use -# more than this amount of memory. -index_summary_capacity_in_mb: - -# How frequently index summaries should be resampled. This is done -# periodically to redistribute memory from the fixed-size pool to sstables -# proportional their recent read rates. Setting to -1 will disable this -# process, leaving existing index summaries at their current sampling level. -index_summary_resize_interval_in_minutes: 60 - -# Whether to, when doing sequential writing, fsync() at intervals in -# order to force the operating system to flush the dirty -# buffers. Enable this to avoid sudden dirty buffer flushing from -# impacting read latencies. Almost always a good idea on SSDs; not -# necessarily on platters. -trickle_fsync: false -trickle_fsync_interval_in_kb: 10240 - -# TCP port, for commands and data -# For security reasons, you should not expose this port to the internet. Firewall it if needed. -storage_port: 7000 - -# SSL port, for encrypted communication. Unused unless enabled in -# encryption_options -# For security reasons, you should not expose this port to the internet. Firewall it if needed. -ssl_storage_port: 7001 - -# Address or interface to bind to and tell other Cassandra nodes to connect to. -# You _must_ change this if you want multiple nodes to be able to communicate! -# -# Set listen_address OR listen_interface, not both. -# -# Leaving it blank leaves it up to InetAddress.getLocalHost(). This -# will always do the Right Thing _if_ the node is properly configured -# (hostname, name resolution, etc), and the Right Thing is to use the -# address associated with the hostname (it might not be). -# -# Setting listen_address to 0.0.0.0 is always wrong. -# -listen_address: localhost - -# Set listen_address OR listen_interface, not both. Interfaces must correspond -# to a single address, IP aliasing is not supported. -# listen_interface: eth0 - -# If you choose to specify the interface by name and the interface has an ipv4 and an ipv6 address -# you can specify which should be chosen using listen_interface_prefer_ipv6. If false the first ipv4 -# address will be used. If true the first ipv6 address will be used. Defaults to false preferring -# ipv4. If there is only one address it will be selected regardless of ipv4/ipv6. -# listen_interface_prefer_ipv6: false - -# Address to broadcast to other Cassandra nodes -# Leaving this blank will set it to the same value as listen_address -# broadcast_address: 1.2.3.4 - -# When using multiple physical network interfaces, set this -# to true to listen on broadcast_address in addition to -# the listen_address, allowing nodes to communicate in both -# interfaces. -# Ignore this property if the network configuration automatically -# routes between the public and private networks such as EC2. -# listen_on_broadcast_address: false - -# Internode authentication backend, implementing IInternodeAuthenticator; -# used to allow/disallow connections from peer nodes. -# internode_authenticator: org.apache.cassandra.auth.AllowAllInternodeAuthenticator - -# Whether to start the native transport server. -# Please note that the address on which the native transport is bound is the -# same as the rpc_address. The port however is different and specified below. -start_native_transport: true -# port for the CQL native transport to listen for clients on -# For security reasons, you should not expose this port to the internet. Firewall it if needed. -native_transport_port: 9042 -# Enabling native transport encryption in client_encryption_options allows you to either use -# encryption for the standard port or to use a dedicated, additional port along with the unencrypted -# standard native_transport_port. -# Enabling client encryption and keeping native_transport_port_ssl disabled will use encryption -# for native_transport_port. Setting native_transport_port_ssl to a different value -# from native_transport_port will use encryption for native_transport_port_ssl while -# keeping native_transport_port unencrypted. -# native_transport_port_ssl: 9142 -# The maximum threads for handling requests when the native transport is used. -# This is similar to rpc_max_threads though the default differs slightly (and -# there is no native_transport_min_threads, idle threads will always be stopped -# after 30 seconds). -# native_transport_max_threads: 128 -# -# The maximum size of allowed frame. Frame (requests) larger than this will -# be rejected as invalid. The default is 256MB. If you're changing this parameter, -# you may want to adjust max_value_size_in_mb accordingly. This should be positive and less than 2048. -# native_transport_max_frame_size_in_mb: 256 - -# The maximum number of concurrent client connections. -# The default is -1, which means unlimited. -# native_transport_max_concurrent_connections: -1 - -# The maximum number of concurrent client connections per source ip. -# The default is -1, which means unlimited. -# native_transport_max_concurrent_connections_per_ip: -1 - -# Whether to start the thrift rpc server. -start_rpc: false - -# The address or interface to bind the Thrift RPC service and native transport -# server to. -# -# Set rpc_address OR rpc_interface, not both. -# -# Leaving rpc_address blank has the same effect as on listen_address -# (i.e. it will be based on the configured hostname of the node). -# -# Note that unlike listen_address, you can specify 0.0.0.0, but you must also -# set broadcast_rpc_address to a value other than 0.0.0.0. -# -# For security reasons, you should not expose this port to the internet. Firewall it if needed. -rpc_address: localhost - -# Set rpc_address OR rpc_interface, not both. Interfaces must correspond -# to a single address, IP aliasing is not supported. -# rpc_interface: eth1 - -# If you choose to specify the interface by name and the interface has an ipv4 and an ipv6 address -# you can specify which should be chosen using rpc_interface_prefer_ipv6. If false the first ipv4 -# address will be used. If true the first ipv6 address will be used. Defaults to false preferring -# ipv4. If there is only one address it will be selected regardless of ipv4/ipv6. -# rpc_interface_prefer_ipv6: false - -# port for Thrift to listen for clients on -rpc_port: 9160 - -# RPC address to broadcast to drivers and other Cassandra nodes. This cannot -# be set to 0.0.0.0. If left blank, this will be set to the value of -# rpc_address. If rpc_address is set to 0.0.0.0, broadcast_rpc_address must -# be set. -# broadcast_rpc_address: 1.2.3.4 - -# enable or disable keepalive on rpc/native connections -rpc_keepalive: true - -# Cassandra provides two out-of-the-box options for the RPC Server: -# -# sync -# One thread per thrift connection. For a very large number of clients, memory -# will be your limiting factor. On a 64 bit JVM, 180KB is the minimum stack size -# per thread, and that will correspond to your use of virtual memory (but physical memory -# may be limited depending on use of stack space). -# -# hsha -# Stands for "half synchronous, half asynchronous." All thrift clients are handled -# asynchronously using a small number of threads that does not vary with the amount -# of thrift clients (and thus scales well to many clients). The rpc requests are still -# synchronous (one thread per active request). If hsha is selected then it is essential -# that rpc_max_threads is changed from the default value of unlimited. -# -# The default is sync because on Windows hsha is about 30% slower. On Linux, -# sync/hsha performance is about the same, with hsha of course using less memory. -# -# Alternatively, can provide your own RPC server by providing the fully-qualified class name -# of an o.a.c.t.TServerFactory that can create an instance of it. -rpc_server_type: sync - -# Uncomment rpc_min|max_thread to set request pool size limits. -# -# Regardless of your choice of RPC server (see above), the number of maximum requests in the -# RPC thread pool dictates how many concurrent requests are possible (but if you are using the sync -# RPC server, it also dictates the number of clients that can be connected at all). -# -# The default is unlimited and thus provides no protection against clients overwhelming the server. You are -# encouraged to set a maximum that makes sense for you in production, but do keep in mind that -# rpc_max_threads represents the maximum number of client requests this server may execute concurrently. -# -# rpc_min_threads: 16 -# rpc_max_threads: 2048 - -# uncomment to set socket buffer sizes on rpc connections -# rpc_send_buff_size_in_bytes: -# rpc_recv_buff_size_in_bytes: - -# Uncomment to set socket buffer size for internode communication -# Note that when setting this, the buffer size is limited by net.core.wmem_max -# and when not setting it it is defined by net.ipv4.tcp_wmem -# See also: -# /proc/sys/net/core/wmem_max -# /proc/sys/net/core/rmem_max -# /proc/sys/net/ipv4/tcp_wmem -# /proc/sys/net/ipv4/tcp_wmem -# and 'man tcp' -# internode_send_buff_size_in_bytes: - -# Uncomment to set socket buffer size for internode communication -# Note that when setting this, the buffer size is limited by net.core.wmem_max -# and when not setting it it is defined by net.ipv4.tcp_wmem -# internode_recv_buff_size_in_bytes: - -# Frame size for thrift (maximum message length). -thrift_framed_transport_size_in_mb: 15 - -# Set to true to have Cassandra create a hard link to each sstable -# flushed or streamed locally in a backups/ subdirectory of the -# keyspace data. Removing these links is the operator's -# responsibility. -incremental_backups: false - -# Whether or not to take a snapshot before each compaction. Be -# careful using this option, since Cassandra won't clean up the -# snapshots for you. Mostly useful if you're paranoid when there -# is a data format change. -snapshot_before_compaction: false - -# Whether or not a snapshot is taken of the data before keyspace truncation -# or dropping of column families. The STRONGLY advised default of true -# should be used to provide data safety. If you set this flag to false, you will -# lose data on truncation or drop. -auto_snapshot: true - -# Granularity of the collation index of rows within a partition. -# Increase if your rows are large, or if you have a very large -# number of rows per partition. The competing goals are these: -# -# - a smaller granularity means more index entries are generated -# and looking up rows withing the partition by collation column -# is faster -# - but, Cassandra will keep the collation index in memory for hot -# rows (as part of the key cache), so a larger granularity means -# you can cache more hot rows -column_index_size_in_kb: 64 - -# Per sstable indexed key cache entries (the collation index in memory -# mentioned above) exceeding this size will not be held on heap. -# This means that only partition information is held on heap and the -# index entries are read from disk. -# -# Note that this size refers to the size of the -# serialized index information and not the size of the partition. -column_index_cache_size_in_kb: 2 - -# Number of simultaneous compactions to allow, NOT including -# validation "compactions" for anti-entropy repair. Simultaneous -# compactions can help preserve read performance in a mixed read/write -# workload, by mitigating the tendency of small sstables to accumulate -# during a single long running compactions. The default is usually -# fine and if you experience problems with compaction running too -# slowly or too fast, you should look at -# compaction_throughput_mb_per_sec first. -# -# concurrent_compactors defaults to the smaller of (number of disks, -# number of cores), with a minimum of 2 and a maximum of 8. -# -# If your data directories are backed by SSD, you should increase this -# to the number of cores. -#concurrent_compactors: 1 - -# Throttles compaction to the given total throughput across the entire -# system. The faster you insert data, the faster you need to compact in -# order to keep the sstable count down, but in general, setting this to -# 16 to 32 times the rate you are inserting data is more than sufficient. -# Setting this to 0 disables throttling. Note that this account for all types -# of compaction, including validation compaction. -compaction_throughput_mb_per_sec: 16 - -# When compacting, the replacement sstable(s) can be opened before they -# are completely written, and used in place of the prior sstables for -# any range that has been written. This helps to smoothly transfer reads -# between the sstables, reducing page cache churn and keeping hot rows hot -sstable_preemptive_open_interval_in_mb: 50 - -# Throttles all outbound streaming file transfers on this node to the -# given total throughput in Mbps. This is necessary because Cassandra does -# mostly sequential IO when streaming data during bootstrap or repair, which -# can lead to saturating the network connection and degrading rpc performance. -# When unset, the default is 200 Mbps or 25 MB/s. -# stream_throughput_outbound_megabits_per_sec: 200 - -# Throttles all streaming file transfer between the datacenters, -# this setting allows users to throttle inter dc stream throughput in addition -# to throttling all network stream traffic as configured with -# stream_throughput_outbound_megabits_per_sec -# When unset, the default is 200 Mbps or 25 MB/s -# inter_dc_stream_throughput_outbound_megabits_per_sec: 200 - -# How long the coordinator should wait for read operations to complete -read_request_timeout_in_ms: 5000 -# How long the coordinator should wait for seq or index scans to complete -range_request_timeout_in_ms: 10000 -# How long the coordinator should wait for writes to complete -write_request_timeout_in_ms: 2000 -# How long the coordinator should wait for counter writes to complete -counter_write_request_timeout_in_ms: 5000 -# How long a coordinator should continue to retry a CAS operation -# that contends with other proposals for the same row -cas_contention_timeout_in_ms: 1000 -# How long the coordinator should wait for truncates to complete -# (This can be much longer, because unless auto_snapshot is disabled -# we need to flush first so we can snapshot before removing the data.) -truncate_request_timeout_in_ms: 60000 -# The default timeout for other, miscellaneous operations -request_timeout_in_ms: 10000 - -# How long before a node logs slow queries. Select queries that take longer than -# this timeout to execute, will generate an aggregated log message, so that slow queries -# can be identified. Set this value to zero to disable slow query logging. -slow_query_log_timeout_in_ms: 500 - -# Enable operation timeout information exchange between nodes to accurately -# measure request timeouts. If disabled, replicas will assume that requests -# were forwarded to them instantly by the coordinator, which means that -# under overload conditions we will waste that much extra time processing -# already-timed-out requests. -# -# Warning: before enabling this property make sure to ntp is installed -# and the times are synchronized between the nodes. -cross_node_timeout: false - -# Set keep-alive period for streaming -# This node will send a keep-alive message periodically with this period. -# If the node does not receive a keep-alive message from the peer for -# 2 keep-alive cycles the stream session times out and fail -# Default value is 300s (5 minutes), which means stalled stream -# times out in 10 minutes by default -# streaming_keep_alive_period_in_secs: 300 - -# phi value that must be reached for a host to be marked down. -# most users should never need to adjust this. -# phi_convict_threshold: 8 - -# endpoint_snitch -- Set this to a class that implements -# IEndpointSnitch. The snitch has two functions: -# -# - it teaches Cassandra enough about your network topology to route -# requests efficiently -# - it allows Cassandra to spread replicas around your cluster to avoid -# correlated failures. It does this by grouping machines into -# "datacenters" and "racks." Cassandra will do its best not to have -# more than one replica on the same "rack" (which may not actually -# be a physical location) -# -# CASSANDRA WILL NOT ALLOW YOU TO SWITCH TO AN INCOMPATIBLE SNITCH -# ONCE DATA IS INSERTED INTO THE CLUSTER. This would cause data loss. -# This means that if you start with the default SimpleSnitch, which -# locates every node on "rack1" in "datacenter1", your only options -# if you need to add another datacenter are GossipingPropertyFileSnitch -# (and the older PFS). From there, if you want to migrate to an -# incompatible snitch like Ec2Snitch you can do it by adding new nodes -# under Ec2Snitch (which will locate them in a new "datacenter") and -# decommissioning the old ones. -# -# Out of the box, Cassandra provides: -# -# SimpleSnitch: -# Treats Strategy order as proximity. This can improve cache -# locality when disabling read repair. Only appropriate for -# single-datacenter deployments. -# -# GossipingPropertyFileSnitch -# This should be your go-to snitch for production use. The rack -# and datacenter for the local node are defined in -# cassandra-rackdc.properties and propagated to other nodes via -# gossip. If cassandra-topology.properties exists, it is used as a -# fallback, allowing migration from the PropertyFileSnitch. -# -# PropertyFileSnitch: -# Proximity is determined by rack and data center, which are -# explicitly configured in cassandra-topology.properties. -# -# Ec2Snitch: -# Appropriate for EC2 deployments in a single Region. Loads Region -# and Availability Zone information from the EC2 API. The Region is -# treated as the datacenter, and the Availability Zone as the rack. -# Only private IPs are used, so this will not work across multiple -# Regions. -# -# Ec2MultiRegionSnitch: -# Uses public IPs as broadcast_address to allow cross-region -# connectivity. (Thus, you should set seed addresses to the public -# IP as well.) You will need to open the storage_port or -# ssl_storage_port on the public IP firewall. (For intra-Region -# traffic, Cassandra will switch to the private IP after -# establishing a connection.) -# -# RackInferringSnitch: -# Proximity is determined by rack and data center, which are -# assumed to correspond to the 3rd and 2nd octet of each node's IP -# address, respectively. Unless this happens to match your -# deployment conventions, this is best used as an example of -# writing a custom Snitch class and is provided in that spirit. -# -# You can use a custom Snitch by setting this to the full class name -# of the snitch, which will be assumed to be on your classpath. -endpoint_snitch: SimpleSnitch - -# controls how often to perform the more expensive part of host score -# calculation -dynamic_snitch_update_interval_in_ms: 100 -# controls how often to reset all host scores, allowing a bad host to -# possibly recover -dynamic_snitch_reset_interval_in_ms: 600000 -# if set greater than zero and read_repair_chance is < 1.0, this will allow -# 'pinning' of replicas to hosts in order to increase cache capacity. -# The badness threshold will control how much worse the pinned host has to be -# before the dynamic snitch will prefer other replicas over it. This is -# expressed as a double which represents a percentage. Thus, a value of -# 0.2 means Cassandra would continue to prefer the static snitch values -# until the pinned host was 20% worse than the fastest. -dynamic_snitch_badness_threshold: 0.1 - -# request_scheduler -- Set this to a class that implements -# RequestScheduler, which will schedule incoming client requests -# according to the specific policy. This is useful for multi-tenancy -# with a single Cassandra cluster. -# NOTE: This is specifically for requests from the client and does -# not affect inter node communication. -# org.apache.cassandra.scheduler.NoScheduler - No scheduling takes place -# org.apache.cassandra.scheduler.RoundRobinScheduler - Round robin of -# client requests to a node with a separate queue for each -# request_scheduler_id. The scheduler is further customized by -# request_scheduler_options as described below. -request_scheduler: org.apache.cassandra.scheduler.NoScheduler - -# Scheduler Options vary based on the type of scheduler -# -# NoScheduler -# Has no options -# -# RoundRobin -# throttle_limit -# The throttle_limit is the number of in-flight -# requests per client. Requests beyond -# that limit are queued up until -# running requests can complete. -# The value of 80 here is twice the number of -# concurrent_reads + concurrent_writes. -# default_weight -# default_weight is optional and allows for -# overriding the default which is 1. -# weights -# Weights are optional and will default to 1 or the -# overridden default_weight. The weight translates into how -# many requests are handled during each turn of the -# RoundRobin, based on the scheduler id. -# -# request_scheduler_options: -# throttle_limit: 80 -# default_weight: 5 -# weights: -# Keyspace1: 1 -# Keyspace2: 5 - -# request_scheduler_id -- An identifier based on which to perform -# the request scheduling. Currently the only valid option is keyspace. -# request_scheduler_id: keyspace - -# Enable or disable inter-node encryption -# JVM defaults for supported SSL socket protocols and cipher suites can -# be replaced using custom encryption options. This is not recommended -# unless you have policies in place that dictate certain settings, or -# need to disable vulnerable ciphers or protocols in case the JVM cannot -# be updated. -# FIPS compliant settings can be configured at JVM level and should not -# involve changing encryption settings here: -# https://docs.oracle.com/javase/8/docs/technotes/guides/security/jsse/FIPS.html -# *NOTE* No custom encryption options are enabled at the moment -# The available internode options are : all, none, dc, rack -# -# If set to dc cassandra will encrypt the traffic between the DCs -# If set to rack cassandra will encrypt the traffic between the racks -# -# The passwords used in these options must match the passwords used when generating -# the keystore and truststore. For instructions on generating these files, see: -# https://download.oracle.com/javase/6/docs/technotes/guides/security/jsse/JSSERefGuide.html#CreateKeystore -# -server_encryption_options: - internode_encryption: none - keystore: conf/.keystore - keystore_password: cassandra - truststore: conf/.truststore - truststore_password: cassandra - # More advanced defaults below: - # protocol: TLS - # algorithm: SunX509 - # store_type: JKS - # cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA] - # require_client_auth: false - # require_endpoint_verification: false - -# enable or disable client/server encryption. -client_encryption_options: - enabled: false - # If enabled and optional is set to true encrypted and unencrypted connections are handled. - optional: false - keystore: conf/.keystore - keystore_password: cassandra - # require_client_auth: false - # Set trustore and truststore_password if require_client_auth is true - # truststore: conf/.truststore - # truststore_password: cassandra - # More advanced defaults below: - # protocol: TLS - # algorithm: SunX509 - # store_type: JKS - # cipher_suites: [TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA,TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_DHE_RSA_WITH_AES_256_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA] - -# internode_compression controls whether traffic between nodes is -# compressed. -# Can be: -# -# all -# all traffic is compressed -# -# dc -# traffic between different datacenters is compressed -# -# none -# nothing is compressed. -internode_compression: dc - -# Enable or disable tcp_nodelay for inter-dc communication. -# Disabling it will result in larger (but fewer) network packets being sent, -# reducing overhead from the TCP protocol itself, at the cost of increasing -# latency if you block for cross-datacenter responses. -inter_dc_tcp_nodelay: false - -# TTL for different trace types used during logging of the repair process. -tracetype_query_ttl: 86400 -tracetype_repair_ttl: 604800 - -# By default, Cassandra logs GC Pauses greater than 200 ms at INFO level -# This threshold can be adjusted to minimize logging if necessary -# gc_log_threshold_in_ms: 200 - -# If unset, all GC Pauses greater than gc_log_threshold_in_ms will log at -# INFO level -# UDFs (user defined functions) are disabled by default. -# As of Cassandra 3.0 there is a sandbox in place that should prevent execution of evil code. -enable_user_defined_functions: false - -# Enables scripted UDFs (JavaScript UDFs). -# Java UDFs are always enabled, if enable_user_defined_functions is true. -# Enable this option to be able to use UDFs with "language javascript" or any custom JSR-223 provider. -# This option has no effect, if enable_user_defined_functions is false. -enable_scripted_user_defined_functions: false - -# Enables materialized view creation on this node. -# Materialized views are considered experimental and are not recommended for production use. -enable_materialized_views: true - -# The default Windows kernel timer and scheduling resolution is 15.6ms for power conservation. -# Lowering this value on Windows can provide much tighter latency and better throughput, however -# some virtualized environments may see a negative performance impact from changing this setting -# below their system default. The sysinternals 'clockres' tool can confirm your system's default -# setting. -windows_timer_interval: 1 - - -# Enables encrypting data at-rest (on disk). Different key providers can be plugged in, but the default reads from -# a JCE-style keystore. A single keystore can hold multiple keys, but the one referenced by -# the "key_alias" is the only key that will be used for encrypt opertaions; previously used keys -# can still (and should!) be in the keystore and will be used on decrypt operations -# (to handle the case of key rotation). -# -# It is strongly recommended to download and install Java Cryptography Extension (JCE) -# Unlimited Strength Jurisdiction Policy Files for your version of the JDK. -# (current link: https://www.oracle.com/technetwork/java/javase/downloads/jce8-download-2133166.html) -# -# Currently, only the following file types are supported for transparent data encryption, although -# more are coming in future cassandra releases: commitlog, hints -transparent_data_encryption_options: - enabled: false - chunk_length_kb: 64 - cipher: AES/CBC/PKCS5Padding - key_alias: testing:1 - # CBC IV length for AES needs to be 16 bytes (which is also the default size) - # iv_length: 16 - key_provider: - - class_name: org.apache.cassandra.security.JKSKeyProvider - parameters: - - keystore: conf/.keystore - keystore_password: cassandra - store_type: JCEKS - key_password: cassandra - - -##################### -# SAFETY THRESHOLDS # -##################### - -# When executing a scan, within or across a partition, we need to keep the -# tombstones seen in memory so we can return them to the coordinator, which -# will use them to make sure other replicas also know about the deleted rows. -# With workloads that generate a lot of tombstones, this can cause performance -# problems and even exaust the server heap. -# (https://www.datastax.com/dev/blog/cassandra-anti-patterns-queues-and-queue-like-datasets) -# Adjust the thresholds here if you understand the dangers and want to -# scan more tombstones anyway. These thresholds may also be adjusted at runtime -# using the StorageService mbean. -tombstone_warn_threshold: 1000 -tombstone_failure_threshold: 100000 - -# Log WARN on any multiple-partition batch size exceeding this value. 5kb per batch by default. -# Caution should be taken on increasing the size of this threshold as it can lead to node instability. -batch_size_warn_threshold_in_kb: 5 - -# Fail any multiple-partition batch exceeding this value. 50kb (10x warn threshold) by default. -batch_size_fail_threshold_in_kb: 50 - -# Log WARN on any batches not of type LOGGED than span across more partitions than this limit -unlogged_batch_across_partitions_warn_threshold: 10 - -# Log a warning when compacting partitions larger than this value -compaction_large_partition_warning_threshold_mb: 100 - -# GC Pauses greater than gc_warn_threshold_in_ms will be logged at WARN level -# Adjust the threshold based on your application throughput requirement -# By default, Cassandra logs GC Pauses greater than 200 ms at INFO level -gc_warn_threshold_in_ms: 1000 - -# Maximum size of any value in SSTables. Safety measure to detect SSTable corruption -# early. Any value size larger than this threshold will result into marking an SSTable -# as corrupted. This should be positive and less than 2048. -# max_value_size_in_mb: 256 - -# Back-pressure settings # -# If enabled, the coordinator will apply the back-pressure strategy specified below to each mutation -# sent to replicas, with the aim of reducing pressure on overloaded replicas. -back_pressure_enabled: false -# The back-pressure strategy applied. -# The default implementation, RateBasedBackPressure, takes three arguments: -# high ratio, factor, and flow type, and uses the ratio between incoming mutation responses and outgoing mutation requests. -# If below high ratio, outgoing mutations are rate limited according to the incoming rate decreased by the given factor; -# if above high ratio, the rate limiting is increased by the given factor; -# such factor is usually best configured between 1 and 10, use larger values for a faster recovery -# at the expense of potentially more dropped mutations; -# the rate limiting is applied according to the flow type: if FAST, it's rate limited at the speed of the fastest replica, -# if SLOW at the speed of the slowest one. -# New strategies can be added. Implementors need to implement org.apache.cassandra.net.BackpressureStrategy and -# provide a public constructor accepting a Map. -back_pressure_strategy: - - class_name: org.apache.cassandra.net.RateBasedBackPressure - parameters: - - high_ratio: 0.90 - factor: 5 - flow: FAST - -# Coalescing Strategies # -# Coalescing multiples messages turns out to significantly boost message processing throughput (think doubling or more). -# On bare metal, the floor for packet processing throughput is high enough that many applications won't notice, but in -# virtualized environments, the point at which an application can be bound by network packet processing can be -# surprisingly low compared to the throughput of task processing that is possible inside a VM. It's not that bare metal -# doesn't benefit from coalescing messages, it's that the number of packets a bare metal network interface can process -# is sufficient for many applications such that no load starvation is experienced even without coalescing. -# There are other benefits to coalescing network messages that are harder to isolate with a simple metric like messages -# per second. By coalescing multiple tasks together, a network thread can process multiple messages for the cost of one -# trip to read from a socket, and all the task submission work can be done at the same time reducing context switching -# and increasing cache friendliness of network message processing. -# See CASSANDRA-8692 for details. - -# Strategy to use for coalescing messages in OutboundTcpConnection. -# Can be fixed, movingaverage, timehorizon, disabled (default). -# You can also specify a subclass of CoalescingStrategies.CoalescingStrategy by name. -# otc_coalescing_strategy: DISABLED - -# How many microseconds to wait for coalescing. For fixed strategy this is the amount of time after the first -# message is received before it will be sent with any accompanying messages. For moving average this is the -# maximum amount of time that will be waited as well as the interval at which messages must arrive on average -# for coalescing to be enabled. -# otc_coalescing_window_us: 200 - -# Do not try to coalesce messages if we already got that many messages. This should be more than 2 and less than 128. -# otc_coalescing_enough_coalesced_messages: 8 - -# How many milliseconds to wait between two expiration runs on the backlog (queue) of the OutboundTcpConnection. -# Expiration is done if messages are piling up in the backlog. Droppable messages are expired to free the memory -# taken by expired messages. The interval should be between 0 and 1000, and in most installations the default value -# will be appropriate. A smaller value could potentially expire messages slightly sooner at the expense of more CPU -# time and queue contention while iterating the backlog of messages. -# An interval of 0 disables any wait time, which is the behavior of former Cassandra versions. -# -# otc_backlog_expiration_interval_ms: 200 diff --git a/spring-cloud-vault-config-rabbitmq/.flattened-pom.xml b/spring-cloud-vault-config-rabbitmq/.flattened-pom.xml new file mode 100644 index 00000000..41617b59 --- /dev/null +++ b/spring-cloud-vault-config-rabbitmq/.flattened-pom.xml @@ -0,0 +1,145 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-vault-parent + 4.1.0-SNAPSHOT + .. + + org.springframework.cloud + spring-cloud-vault-config-rabbitmq + 4.1.0-SNAPSHOT + Spring Cloud Vault Config RabbitMQ support + Spring Cloud Vault Config RabbitMQ support + https://spring.io/spring-cloud/spring-cloud-vault-parent/spring-cloud-vault-config-rabbitmq + + Pivotal Software, Inc. + https://www.spring.io + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + Copyright 2014-2021 the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. + + See the License for the specific language governing permissions and + limitations under the License. + + + + + dsyer + Dave Syer + dsyer at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + sgibb + Spencer Gibb + sgibb at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + mgrzejszczak + Marcin Grzejszczak + mgrzejszczak at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + rbaxter + Ryan Baxter + rbaxter at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + omaciaszeksharma + Olga Maciaszek-Sharma + omaciaszeksharma at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + + scm:git:git://github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-config-rabbitmq + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-config-rabbitmq + https://github.com/spring-cloud/spring-cloud-vault/spring-cloud-vault-config-rabbitmq + + + + org.springframework.cloud + spring-cloud-vault-config + 4.1.0-SNAPSHOT + compile + + + org.springframework.boot + spring-boot-autoconfigure-processor + 3.2.0-SNAPSHOT + compile + true + + + org.springframework.boot + spring-boot-configuration-processor + 3.2.0-SNAPSHOT + compile + true + + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + + org.hibernate.validator + hibernate-validator + 8.0.0.Final + provided + + + org.springframework.boot + spring-boot-autoconfigure + 3.2.0-SNAPSHOT + provided + + + org.springframework.boot + spring-boot-starter + 3.2.0-SNAPSHOT + provided + + + diff --git a/spring-cloud-vault-config-rabbitmq/pom.xml b/spring-cloud-vault-config-rabbitmq/pom.xml deleted file mode 100644 index d4780563..00000000 --- a/spring-cloud-vault-config-rabbitmq/pom.xml +++ /dev/null @@ -1,66 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-vault-parent - 4.1.0-SNAPSHOT - .. - - - spring-cloud-vault-config-rabbitmq - jar - - Spring Cloud Vault Config RabbitMQ support - Spring Cloud Vault Config RabbitMQ support - - - - - org.springframework.cloud - spring-cloud-vault-config - - - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - - org.junit.vintage - junit-vintage-engine - test - - - - org.apache.httpcomponents.client5 - httpclient5 - test - - - - org.springframework.boot - spring-boot-starter-amqp - test - - - - org.springframework.cloud - spring-cloud-vault-config - test-jar - - - - diff --git a/spring-cloud-vault-config-rabbitmq/src/main/java/org/springframework/cloud/vault/config/rabbitmq/VaultConfigRabbitMqBootstrapConfiguration.java b/spring-cloud-vault-config-rabbitmq/src/main/java/org/springframework/cloud/vault/config/rabbitmq/VaultConfigRabbitMqBootstrapConfiguration.java deleted file mode 100644 index b8668c7b..00000000 --- a/spring-cloud-vault-config-rabbitmq/src/main/java/org/springframework/cloud/vault/config/rabbitmq/VaultConfigRabbitMqBootstrapConfiguration.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.rabbitmq; - -import java.util.HashMap; -import java.util.Map; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.vault.config.PropertyNameTransformer; -import org.springframework.cloud.vault.config.SecretBackendMetadata; -import org.springframework.cloud.vault.config.SecretBackendMetadataFactory; -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.util.Assert; -import org.springframework.vault.core.util.PropertyTransformer; - -/** - * Bootstrap configuration providing support for the RabbitMQ secret backend. - * - * @author Mark Paluch - */ -@Configuration(proxyBeanMethods = false) -@EnableConfigurationProperties(VaultRabbitMqProperties.class) -public class VaultConfigRabbitMqBootstrapConfiguration { - - @Bean - @ConditionalOnMissingBean - public RabbitMqSecretBackendMetadataFactory rabbitMqSecureBackendAccessorFactory() { - return new RabbitMqSecretBackendMetadataFactory(); - } - - /** - * {@link SecretBackendMetadataFactory} for RabbitMq integration using - * {@link VaultRabbitMqProperties}. - */ - public static class RabbitMqSecretBackendMetadataFactory - implements SecretBackendMetadataFactory { - - /** - * Creates a {@link SecretBackendMetadata} for a secret backend using - * {@link VaultRabbitMqProperties}. This accessor transforms Vault's - * username/password property names to names provided with - * {@link VaultRabbitMqProperties#getUsernameProperty()} and - * {@link VaultRabbitMqProperties#getPasswordProperty()}. - * @param properties must not be {@literal null}. - * @return the {@link SecretBackendMetadata} - */ - static SecretBackendMetadata forRabbitMq(final VaultRabbitMqProperties properties) { - - Assert.notNull(properties, "VaultRabbitMqProperties must not be null"); - - PropertyNameTransformer transformer = new PropertyNameTransformer(); - transformer.addKeyTransformation("username", properties.getUsernameProperty()); - transformer.addKeyTransformation("password", properties.getPasswordProperty()); - - return new SecretBackendMetadata() { - - @Override - public String getName() { - return String.format("%s with Role %s", properties.getBackend(), properties.getRole()); - } - - @Override - public String getPath() { - return String.format("%s/creds/%s", properties.getBackend(), properties.getRole()); - } - - @Override - public PropertyTransformer getPropertyTransformer() { - return transformer; - } - - @Override - public Map getVariables() { - - Map variables = new HashMap<>(); - - variables.put("backend", properties.getBackend()); - variables.put("key", String.format("creds/%s", properties.getRole())); - - return variables; - } - }; - } - - @Override - public SecretBackendMetadata createMetadata(VaultRabbitMqProperties backendDescriptor) { - return forRabbitMq(backendDescriptor); - } - - @Override - public boolean supports(VaultSecretBackendDescriptor backendDescriptor) { - return backendDescriptor instanceof VaultRabbitMqProperties; - } - - } - -} diff --git a/spring-cloud-vault-config-rabbitmq/src/main/java/org/springframework/cloud/vault/config/rabbitmq/VaultRabbitMqProperties.java b/spring-cloud-vault-config-rabbitmq/src/main/java/org/springframework/cloud/vault/config/rabbitmq/VaultRabbitMqProperties.java deleted file mode 100644 index 25382b0f..00000000 --- a/spring-cloud-vault-config-rabbitmq/src/main/java/org/springframework/cloud/vault/config/rabbitmq/VaultRabbitMqProperties.java +++ /dev/null @@ -1,100 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.rabbitmq; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.cloud.vault.config.VaultSecretBackendDescriptor; -import org.springframework.lang.Nullable; - -/** - * Configuration properties for Vault using the RabbitMQ integration. - * - * @author Mark Paluch - */ -@ConfigurationProperties("spring.cloud.vault.rabbitmq") -public class VaultRabbitMqProperties implements VaultSecretBackendDescriptor { - - /** - * Enable rabbitmq backend usage. - */ - private boolean enabled = false; - - /** - * Role name for credentials. - */ - @Nullable - private String role; - - /** - * rabbitmq backend path. - */ - private String backend = "rabbitmq"; - - /** - * Target property for the obtained username. - */ - private String usernameProperty = "spring.rabbitmq.username"; - - /** - * Target property for the obtained password. - */ - private String passwordProperty = "spring.rabbitmq.password"; - - @Override - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Nullable - public String getRole() { - return this.role; - } - - public void setRole(@Nullable String role) { - this.role = role; - } - - @Override - public String getBackend() { - return this.backend; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - public String getUsernameProperty() { - return this.usernameProperty; - } - - public void setUsernameProperty(String usernameProperty) { - this.usernameProperty = usernameProperty; - } - - public String getPasswordProperty() { - return this.passwordProperty; - } - - public void setPasswordProperty(String passwordProperty) { - this.passwordProperty = passwordProperty; - } - -} diff --git a/spring-cloud-vault-config-rabbitmq/src/main/java/org/springframework/cloud/vault/config/rabbitmq/package-info.java b/spring-cloud-vault-config-rabbitmq/src/main/java/org/springframework/cloud/vault/config/rabbitmq/package-info.java deleted file mode 100644 index c4392f63..00000000 --- a/spring-cloud-vault-config-rabbitmq/src/main/java/org/springframework/cloud/vault/config/rabbitmq/package-info.java +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * RabbitMQ integration with Vault. - * @author Mark Paluch - */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields -package org.springframework.cloud.vault.config.rabbitmq; diff --git a/spring-cloud-vault-config-rabbitmq/src/main/resources/META-INF/spring.factories b/spring-cloud-vault-config-rabbitmq/src/main/resources/META-INF/spring.factories deleted file mode 100644 index 8a24409f..00000000 --- a/spring-cloud-vault-config-rabbitmq/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,9 +0,0 @@ -# Bootstrap Configuration -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.vault.config.rabbitmq.VaultConfigRabbitMqBootstrapConfiguration - -org.springframework.cloud.vault.config.SecretBackendMetadataFactory=\ -org.springframework.cloud.vault.config.rabbitmq.VaultConfigRabbitMqBootstrapConfiguration.RabbitMqSecretBackendMetadataFactory - -org.springframework.cloud.vault.config.VaultSecretBackendDescriptor=\ -org.springframework.cloud.vault.config.rabbitmq.VaultRabbitMqProperties diff --git a/spring-cloud-vault-config-rabbitmq/src/test/java/org/springframework/cloud/vault/config/rabbitmq/RabbitMqSecretIntegrationTests.java b/spring-cloud-vault-config-rabbitmq/src/test/java/org/springframework/cloud/vault/config/rabbitmq/RabbitMqSecretIntegrationTests.java deleted file mode 100644 index 12ca46d6..00000000 --- a/spring-cloud-vault-config-rabbitmq/src/test/java/org/springframework/cloud/vault/config/rabbitmq/RabbitMqSecretIntegrationTests.java +++ /dev/null @@ -1,107 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.rabbitmq; - -import java.net.InetSocketAddress; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.Before; -import org.junit.Ignore; -import org.junit.Test; - -import org.springframework.cloud.vault.config.VaultConfigTemplate; -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.Version; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; -import static org.springframework.cloud.vault.config.rabbitmq.VaultConfigRabbitMqBootstrapConfiguration.RabbitMqSecretBackendMetadataFactory.forRabbitMq; - -/** - * Integration tests for {@link VaultConfigTemplate} using the rabbitmq secret backend. - * This test requires a running RabbitMQ instance, see {@link #RABBITMQ_URI}. - * - * @author Mark Paluch - */ -@Ignore -public class RabbitMqSecretIntegrationTests extends IntegrationTestSupport { - - private static final int RABBITMQ_HTTP_MANAGEMENT_PORT = 15672; - - private static final String RABBITMQ_HOST = "localhost"; - - private static final String RABBITMQ_USERNAME = "guest"; - - private static final String RABBITMQ_PASSWORD = "guest"; - - private static final String RABBITMQ_URI = String.format("http://%s:%d", RABBITMQ_HOST, - RABBITMQ_HTTP_MANAGEMENT_PORT); - - private static final String VHOSTS_ROLE = "{\"/\":{\"write\": \".*\", \"read\": \".*\"}}"; - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigTemplate configOperations; - - private VaultRabbitMqProperties rabbitmq = new VaultRabbitMqProperties(); - - /** - * Initialize the rabbitmq secret backend. - */ - @Before - public void setUp() { - - assumeTrue(CanConnect.to(new InetSocketAddress(RABBITMQ_HOST, RABBITMQ_HTTP_MANAGEMENT_PORT))); - assumeTrue(prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.2"))); - - this.rabbitmq.setEnabled(true); - this.rabbitmq.setRole("readonly"); - - if (!prepare().hasSecretBackend(this.rabbitmq.getBackend())) { - prepare().mountSecret(this.rabbitmq.getBackend()); - } - - Map connection = new HashMap<>(); - connection.put("connection_uri", RABBITMQ_URI); - connection.put("username", RABBITMQ_USERNAME); - connection.put("password", RABBITMQ_PASSWORD); - - VaultOperations vaultOperations = prepare().getVaultOperations(); - - vaultOperations.write(String.format("%s/config/connection", this.rabbitmq.getBackend()), connection); - - vaultOperations.write(String.format("%s/roles/%s", this.rabbitmq.getBackend(), this.rabbitmq.getRole()), - Collections.singletonMap("vhosts", VHOSTS_ROLE)); - - this.configOperations = new VaultConfigTemplate(vaultOperations, this.vaultProperties); - } - - @Test - public void shouldCreateCredentialsCorrectly() { - - Map secretProperties = this.configOperations.read(forRabbitMq(this.rabbitmq)).getData(); - - assertThat(secretProperties).containsKeys("spring.rabbitmq.username", "spring.rabbitmq.password"); - } - -} diff --git a/spring-cloud-vault-config-rabbitmq/src/test/java/org/springframework/cloud/vault/config/rabbitmq/VaultConfigRabbitMqBootstrapConfigurationTests.java b/spring-cloud-vault-config-rabbitmq/src/test/java/org/springframework/cloud/vault/config/rabbitmq/VaultConfigRabbitMqBootstrapConfigurationTests.java deleted file mode 100644 index a7bf8d50..00000000 --- a/spring-cloud-vault-config-rabbitmq/src/test/java/org/springframework/cloud/vault/config/rabbitmq/VaultConfigRabbitMqBootstrapConfigurationTests.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.rabbitmq; - -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.config.KeyValueSecretBackendMetadata; -import org.springframework.cloud.vault.config.SecretBackendMetadata; -import org.springframework.cloud.vault.config.rabbitmq.VaultConfigRabbitMqBootstrapConfiguration.RabbitMqSecretBackendMetadataFactory; -import org.springframework.cloud.vault.config.rabbitmq.VaultConfigRabbitMqBootstrapConfigurationTests.CustomBootstrapConfiguration; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link VaultConfigRabbitMqBootstrapConfigurationTests}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = CustomBootstrapConfiguration.class, - properties = { "VaultConfigRabbitMqBootstrapConfigurationTests.custom.config=true", - "spring.cloud.vault.rabbitmq.role=foo", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigRabbitMqBootstrapConfigurationTests extends IntegrationTestSupport { - - @Autowired - RabbitMqSecretBackendMetadataFactory factory; - - @Autowired - VaultRabbitMqProperties properties; - - @Test - public void shouldApplyCustomConfiguration() { - - SecretBackendMetadata metadata = this.factory.createMetadata(this.properties); - - assertThat(metadata).isInstanceOf(KeyValueSecretBackendMetadata.class); - assertThat(metadata.getPath()).isEqualTo(this.properties.getRole()); - } - - @Configuration(proxyBeanMethods = false) - public static class CustomBootstrapConfiguration { - - @Bean - @ConditionalOnProperty("VaultConfigRabbitMqBootstrapConfigurationTests.custom.config") - RabbitMqSecretBackendMetadataFactory customFactory() { - - return new RabbitMqSecretBackendMetadataFactory() { - @Override - public SecretBackendMetadata createMetadata(VaultRabbitMqProperties backendDescriptor) { - return KeyValueSecretBackendMetadata.create(backendDescriptor.getRole()); - } - }; - } - - } - -} diff --git a/spring-cloud-vault-config-rabbitmq/src/test/java/org/springframework/cloud/vault/config/rabbitmq/VaultConfigRabbitMqTests.java b/spring-cloud-vault-config-rabbitmq/src/test/java/org/springframework/cloud/vault/config/rabbitmq/VaultConfigRabbitMqTests.java deleted file mode 100644 index ff3bc663..00000000 --- a/spring-cloud-vault-config-rabbitmq/src/test/java/org/springframework/cloud/vault/config/rabbitmq/VaultConfigRabbitMqTests.java +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config.rabbitmq; - -import java.net.InetSocketAddress; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import com.rabbitmq.client.Connection; -import com.rabbitmq.client.ConnectionFactory; -import org.junit.BeforeClass; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.CanConnect; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests using the rabbitmq secret backend. In case this test should fail - * because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigRabbitMqTests.TestApplication.class, - properties = { "spring.cloud.vault.rabbitmq.enabled=true", "spring.cloud.vault.rabbitmq.role=readonly", - "spring.rabbitmq.address=localhost", "spring.cloud.bootstrap.enabled=true" }) -@Ignore -public class VaultConfigRabbitMqTests { - - private static final int RABBITMQ_HTTP_MANAGEMENT_PORT = 15672; - - private static final int RABBITMQ_PORT = 5672; - - private static final String RABBITMQ_HOST = "localhost"; - - private static final String RABBITMQ_USERNAME = "guest"; - - private static final String RABBITMQ_PASSWORD = "guest"; - - private static final String RABBITMQ_URI = String.format("http://%s:%d", RABBITMQ_HOST, - RABBITMQ_HTTP_MANAGEMENT_PORT); - - private static final String VHOSTS_ROLE = "{\"/\":{\"write\": \".*\", \"read\": \".*\"}}"; - - @Value("${spring.rabbitmq.username}") - String username; - - @Value("${spring.rabbitmq.password}") - String password; - - @Autowired - org.springframework.amqp.rabbit.connection.ConnectionFactory connectionFactory; - - /** - * Initialize the rabbitmq secret backend. - */ - @BeforeClass - public static void beforeClass() { - - assumeTrue(CanConnect.to(new InetSocketAddress(RABBITMQ_HOST, RABBITMQ_HTTP_MANAGEMENT_PORT))); - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.2"))); - - if (!vaultRule.prepare().hasSecretBackend("rabbitmq")) { - vaultRule.prepare().mountSecret("rabbitmq"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - Map connection = new HashMap<>(); - connection.put("connection_uri", RABBITMQ_URI); - connection.put("username", RABBITMQ_USERNAME); - connection.put("password", RABBITMQ_PASSWORD); - - vaultOperations.write(String.format("rabbitmq/config/connection"), connection); - - vaultOperations.write(String.format("rabbitmq/roles/readonly"), - Collections.singletonMap("vhosts", VHOSTS_ROLE)); - } - - @Test - public void shouldConnectSpringConnectionFactory() { - this.connectionFactory.createConnection().close(); - } - - @Test - public void shouldConnectUsingRabbitMQClient() throws Exception { - - ConnectionFactory factory = new ConnectionFactory(); - factory.setHost(RABBITMQ_HOST); - factory.setPort(RABBITMQ_PORT); - factory.setUsername(this.username); - factory.setPassword(this.password); - - try (Connection connection = factory.newConnection()) { - connection.createChannel().close(); - } - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config-rabbitmq/src/test/resources/META-INF/spring.factories b/spring-cloud-vault-config-rabbitmq/src/test/resources/META-INF/spring.factories deleted file mode 100644 index 18c28b38..00000000 --- a/spring-cloud-vault-config-rabbitmq/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,4 +0,0 @@ -# Bootstrap Configuration -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.vault.config.rabbitmq.VaultConfigRabbitMqBootstrapConfigurationTests.CustomBootstrapConfiguration,\ -org.springframework.cloud.vault.config.rabbitmq.VaultConfigRabbitMqBootstrapConfiguration diff --git a/spring-cloud-vault-config-rabbitmq/src/test/resources/bootstrap.yml b/spring-cloud-vault-config-rabbitmq/src/test/resources/bootstrap.yml deleted file mode 100644 index c598d962..00000000 --- a/spring-cloud-vault-config-rabbitmq/src/test/resources/bootstrap.yml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - application.name: testVaultApp - cloud.vault.token: 00000000-0000-0000-0000-000000000000 - cloud.vault.ssl.trust-store: file:../work/keystore.jks - cloud.vault.ssl.trust-store-password: changeit diff --git a/spring-cloud-vault-config/.flattened-pom.xml b/spring-cloud-vault-config/.flattened-pom.xml new file mode 100644 index 00000000..a92cbb0e --- /dev/null +++ b/spring-cloud-vault-config/.flattened-pom.xml @@ -0,0 +1,297 @@ + + + 4.0.0 + + org.springframework.cloud + spring-cloud-vault-parent + 4.1.0-SNAPSHOT + .. + + org.springframework.cloud + spring-cloud-vault-config + 4.1.0-SNAPSHOT + Spring Cloud Vault Configuration Integration + Configuration Integration with HashiCorp Vault + https://spring.io/spring-cloud/spring-cloud-vault-parent/spring-cloud-vault-config + + Pivotal Software, Inc. + https://www.spring.io + + + + Apache License, Version 2.0 + https://www.apache.org/licenses/LICENSE-2.0 + Copyright 2014-2021 the original author or authors. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + https://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. + + See the License for the specific language governing permissions and + limitations under the License. + + + + + dsyer + Dave Syer + dsyer at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + sgibb + Spencer Gibb + sgibb at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + lead + + + + mgrzejszczak + Marcin Grzejszczak + mgrzejszczak at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + rbaxter + Ryan Baxter + rbaxter at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + omaciaszeksharma + Olga Maciaszek-Sharma + omaciaszeksharma at pivotal.io + Pivotal Software, Inc. + https://www.spring.io + + developer + + + + + scm:git:git://github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-config + scm:git:ssh://git@github.com/spring-cloud/spring-cloud-vault.git/spring-cloud-vault-config + https://github.com/spring-cloud/spring-cloud-vault/spring-cloud-vault-config + + + + org.springframework + spring-web + 6.0.10-SNAPSHOT + compile + + + org.springframework.cloud + spring-cloud-starter + 4.1.0-SNAPSHOT + compile + + + org.springframework.vault + spring-vault-core + 3.0.2 + compile + + + spring-core + org.springframework + + + spring-beans + org.springframework + + + spring-web + org.springframework + + + + + org.springframework + spring-webflux + 6.0.10-SNAPSHOT + compile + true + + + org.springframework.boot + spring-boot-starter-actuator + 3.2.0-SNAPSHOT + compile + true + + + org.springframework.boot + spring-boot-starter + 3.2.0-SNAPSHOT + compile + true + + + org.springframework.boot + spring-boot-starter-logging + 3.2.0-SNAPSHOT + compile + true + + + io.micrometer + micrometer-tracing + 1.1.2 + compile + true + + + org.apache.httpcomponents.client5 + httpclient5 + 5.2.1 + compile + true + + + org.apache.httpcomponents.core5 + httpcore5 + 5.2.1 + compile + true + + + io.netty + netty-all + 4.1.93.Final + compile + true + + + com.squareup.okhttp3 + okhttp + 4.10.0 + compile + true + + + io.projectreactor + reactor-core + 3.5.7 + compile + true + + + io.projectreactor.netty + reactor-netty + 1.1.8 + compile + + + reactor-netty-http-brave + io.projectreactor.netty + + + true + + + software.amazon.awssdk + auth + 2.17.195 + compile + true + + + org.bouncycastle + bcpkix-jdk15on + 1.70 + compile + true + + + com.google.apis + google-api-services-iam + v1-rev20201112-1.31.0 + compile + true + + + com.google.cloud + google-cloud-iamcredentials + 1.2.2 + compile + + + jackson-core + com.fasterxml.jackson.core + + + httpclient + org.apache.httpcomponents + + + commons-logging + commons-logging + + + true + + + com.google.auth + google-auth-library-oauth2-http + 0.22.2 + compile + true + + + org.springframework.boot + spring-boot-autoconfigure-processor + 3.2.0-SNAPSHOT + compile + true + + + org.springframework.boot + spring-boot-configuration-processor + 3.2.0-SNAPSHOT + compile + true + + + jakarta.validation + jakarta.validation-api + 3.0.2 + provided + + + org.hibernate.validator + hibernate-validator + 8.0.0.Final + provided + + + org.springframework.boot + spring-boot-autoconfigure + 3.2.0-SNAPSHOT + provided + + + diff --git a/spring-cloud-vault-config/pom.xml b/spring-cloud-vault-config/pom.xml deleted file mode 100644 index 7b0bc49a..00000000 --- a/spring-cloud-vault-config/pom.xml +++ /dev/null @@ -1,206 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-vault-parent - 4.1.0-SNAPSHOT - .. - - - spring-cloud-vault-config - Spring Cloud Vault Configuration Integration - Configuration Integration with HashiCorp Vault - - - - - org.springframework - spring-web - - - - org.springframework.cloud - spring-cloud-starter - - - - org.springframework.vault - spring-vault-core - - - - - - - org.springframework - spring-webflux - true - - - - org.springframework.boot - spring-boot-starter-actuator - true - - - - org.springframework.boot - spring-boot-starter - true - - - - org.springframework.boot - spring-boot-starter-logging - true - - - - - - io.micrometer - micrometer-tracing - true - - - - - org.apache.httpcomponents.client5 - httpclient5 - true - - - - org.apache.httpcomponents.core5 - httpcore5 - true - - - - io.netty - netty-all - true - - - - com.squareup.okhttp3 - okhttp - true - - - - - - io.projectreactor - reactor-core - true - - - - io.projectreactor.netty - reactor-netty - true - - - io.projectreactor.netty - reactor-netty-http-brave - - - - - - - software.amazon.awssdk - auth - 2.17.195 - true - - - - - org.bouncycastle - bcpkix-jdk15on - true - - - - - com.google.apis - google-api-services-iam - true - - - - com.google.cloud - google-cloud-iamcredentials - true - - - com.fasterxml.jackson.core - jackson-core - - - org.apache.httpcomponents - httpclient - - - commons-logging - commons-logging - - - - - - com.google.auth - google-auth-library-oauth2-http - true - - - - - org.springframework.boot - spring-boot-autoconfigure-processor - true - - - - org.springframework.boot - spring-boot-configuration-processor - true - - - - - io.projectreactor - reactor-test - test - - - - org.junit.vintage - junit-vintage-engine - test - - - - - - - maven-jar-plugin - - - test-jar - - test-jar - - - - - - - - diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ClientAuthenticationFactory.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ClientAuthenticationFactory.java deleted file mode 100644 index 15078f85..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ClientAuthenticationFactory.java +++ /dev/null @@ -1,462 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.concurrent.atomic.AtomicReference; - -import software.amazon.awssdk.auth.credentials.AwsCredentials; -import software.amazon.awssdk.auth.credentials.AwsCredentialsProvider; -import software.amazon.awssdk.auth.credentials.DefaultCredentialsProvider; - -import org.springframework.beans.BeanUtils; -import org.springframework.boot.system.SystemProperties; -import org.springframework.cloud.vault.config.VaultProperties.AppRoleProperties; -import org.springframework.cloud.vault.config.VaultProperties.AwsIamProperties; -import org.springframework.cloud.vault.config.VaultProperties.AzureMsiProperties; -import org.springframework.util.Assert; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; -import org.springframework.vault.authentication.AppIdAuthentication; -import org.springframework.vault.authentication.AppIdAuthenticationOptions; -import org.springframework.vault.authentication.AppIdUserIdMechanism; -import org.springframework.vault.authentication.AppRoleAuthentication; -import org.springframework.vault.authentication.AppRoleAuthenticationOptions; -import org.springframework.vault.authentication.AppRoleAuthenticationOptions.AppRoleAuthenticationOptionsBuilder; -import org.springframework.vault.authentication.AppRoleAuthenticationOptions.RoleId; -import org.springframework.vault.authentication.AppRoleAuthenticationOptions.SecretId; -import org.springframework.vault.authentication.AwsEc2Authentication; -import org.springframework.vault.authentication.AwsEc2AuthenticationOptions; -import org.springframework.vault.authentication.AwsEc2AuthenticationOptions.Nonce; -import org.springframework.vault.authentication.AwsIamAuthentication; -import org.springframework.vault.authentication.AwsIamAuthenticationOptions; -import org.springframework.vault.authentication.AwsIamAuthenticationOptions.AwsIamAuthenticationOptionsBuilder; -import org.springframework.vault.authentication.AzureMsiAuthentication; -import org.springframework.vault.authentication.AzureMsiAuthenticationOptions; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.ClientCertificateAuthentication; -import org.springframework.vault.authentication.ClientCertificateAuthenticationOptions; -import org.springframework.vault.authentication.CubbyholeAuthentication; -import org.springframework.vault.authentication.CubbyholeAuthenticationOptions; -import org.springframework.vault.authentication.GcpComputeAuthentication; -import org.springframework.vault.authentication.GcpComputeAuthenticationOptions; -import org.springframework.vault.authentication.GcpComputeAuthenticationOptions.GcpComputeAuthenticationOptionsBuilder; -import org.springframework.vault.authentication.IpAddressUserId; -import org.springframework.vault.authentication.KubernetesAuthentication; -import org.springframework.vault.authentication.KubernetesAuthenticationOptions; -import org.springframework.vault.authentication.KubernetesServiceAccountTokenFile; -import org.springframework.vault.authentication.MacAddressUserId; -import org.springframework.vault.authentication.PcfAuthentication; -import org.springframework.vault.authentication.PcfAuthenticationOptions; -import org.springframework.vault.authentication.ResourceCredentialSupplier; -import org.springframework.vault.authentication.StaticUserId; -import org.springframework.vault.authentication.TokenAuthentication; -import org.springframework.vault.support.VaultToken; -import org.springframework.web.client.RestOperations; - -import static java.nio.charset.StandardCharsets.UTF_8; -import software.amazon.awssdk.regions.Region; - -/** - * Factory for {@link ClientAuthentication}. - * - * @author Mark Paluch - * @author Kevin Holditch - * @author Michal Budzyn - * @author Quincy Conduff - * @since 1.1 - */ -class ClientAuthenticationFactory { - - private static final boolean googleCredentialPresent = ClassUtils.isPresent( - "com.google.api.client.googleapis.auth.oauth2.GoogleCredential", - ClientAuthenticationFactory.class.getClassLoader()); - - private static final boolean googleCredentialsPresent = ClassUtils - .isPresent("com.google.auth.oauth2.GoogleCredentials", ClientAuthenticationFactory.class.getClassLoader()); - - private final VaultProperties vaultProperties; - - private final RestOperations restOperations; - - private final RestOperations externalRestOperations; - - ClientAuthenticationFactory(VaultProperties vaultProperties, RestOperations restOperations, - RestOperations externalRestOperations) { - this.vaultProperties = vaultProperties; - this.restOperations = restOperations; - this.externalRestOperations = externalRestOperations; - } - - /** - * @return a new {@link ClientAuthentication}. - */ - ClientAuthentication createClientAuthentication() { - - switch (this.vaultProperties.getAuthentication()) { - - case APPID: - return appIdAuthentication(this.vaultProperties); - - case APPROLE: - return appRoleAuthentication(this.vaultProperties); - - case AWS_EC2: - return awsEc2Authentication(this.vaultProperties); - - case AWS_IAM: - return awsIamAuthentication(this.vaultProperties); - - case AZURE_MSI: - return azureMsiAuthentication(this.vaultProperties); - - case CERT: - return certificateAuthentication(this.vaultProperties); - - case CUBBYHOLE: - return cubbyholeAuthentication(); - - case GCP_GCE: - return gcpGceAuthentication(this.vaultProperties); - - case GCP_IAM: - return gcpIamAuthentication(this.vaultProperties); - - case KUBERNETES: - return kubernetesAuthentication(this.vaultProperties); - - case PCF: - return pcfAuthentication(this.vaultProperties); - - case TOKEN: - return tokenAuthentication(this.vaultProperties); - } - - throw new UnsupportedOperationException( - String.format("Client authentication %s not supported", this.vaultProperties.getAuthentication())); - } - - private ClientAuthentication appIdAuthentication(VaultProperties vaultProperties) { - - VaultProperties.AppIdProperties appId = vaultProperties.getAppId(); - Assert.hasText(appId.getUserId(), "UserId (spring.cloud.vault.app-id.user-id) must not be empty"); - - AppIdAuthenticationOptions authenticationOptions = AppIdAuthenticationOptions.builder() - .appId(vaultProperties.getApplicationName()) // - .path(appId.getAppIdPath()) // - .userIdMechanism(getAppIdMechanism(appId)).build(); - - return new AppIdAuthentication(authenticationOptions, this.restOperations); - } - - private AppIdUserIdMechanism getAppIdMechanism(VaultProperties.AppIdProperties appId) { - - try { - Class userIdClass = ClassUtils.forName(appId.getUserId(), null); - return (AppIdUserIdMechanism) BeanUtils.instantiateClass(userIdClass); - } - catch (ClassNotFoundException ex) { - - switch (appId.getUserId().toUpperCase()) { - - case VaultProperties.AppIdProperties.IP_ADDRESS: - return new IpAddressUserId(); - - case VaultProperties.AppIdProperties.MAC_ADDRESS: - - if (StringUtils.hasText(appId.getNetworkInterface())) { - try { - return new MacAddressUserId(Integer.parseInt(appId.getNetworkInterface())); - } - catch (NumberFormatException e) { - return new MacAddressUserId(appId.getNetworkInterface()); - } - } - - return new MacAddressUserId(); - default: - return new StaticUserId(appId.getUserId()); - } - } - } - - private ClientAuthentication appRoleAuthentication(VaultProperties vaultProperties) { - - AppRoleAuthenticationOptions options = getAppRoleAuthenticationOptions(vaultProperties); - - return new AppRoleAuthentication(options, this.restOperations); - } - - static AppRoleAuthenticationOptions getAppRoleAuthenticationOptions(VaultProperties vaultProperties) { - - AppRoleProperties appRole = vaultProperties.getAppRole(); - - AppRoleAuthenticationOptionsBuilder builder = AppRoleAuthenticationOptions.builder() - .path(appRole.getAppRolePath()); - - if (StringUtils.hasText(appRole.getRole())) { - builder.appRole(appRole.getRole()); - } - - RoleId roleId = getRoleId(vaultProperties, appRole); - SecretId secretId = getSecretId(vaultProperties, appRole); - - builder.roleId(roleId).secretId(secretId); - - return builder.build(); - } - - private static RoleId getRoleId(VaultProperties vaultProperties, AppRoleProperties appRole) { - - if (StringUtils.hasText(appRole.getRoleId())) { - return RoleId.provided(appRole.getRoleId()); - } - - if (StringUtils.hasText(vaultProperties.getToken()) && StringUtils.hasText(appRole.getRole())) { - return RoleId.pull(VaultToken.of(vaultProperties.getToken())); - } - - if (StringUtils.hasText(vaultProperties.getToken())) { - return RoleId.wrapped(VaultToken.of(vaultProperties.getToken())); - } - - throw new IllegalArgumentException( - "Cannot configure RoleId. Any of role-id, initial token, or initial token and role name must be configured."); - } - - private static SecretId getSecretId(VaultProperties vaultProperties, AppRoleProperties appRole) { - - if (StringUtils.hasText(appRole.getSecretId())) { - return SecretId.provided(appRole.getSecretId()); - } - - if (StringUtils.hasText(vaultProperties.getToken()) && StringUtils.hasText(appRole.getRole())) { - return SecretId.pull(VaultToken.of(vaultProperties.getToken())); - } - - if (StringUtils.hasText(vaultProperties.getToken())) { - return SecretId.wrapped(VaultToken.of(vaultProperties.getToken())); - } - - return SecretId.absent(); - } - - private ClientAuthentication awsEc2Authentication(VaultProperties vaultProperties) { - - VaultProperties.AwsEc2Properties awsEc2 = vaultProperties.getAwsEc2(); - - Nonce nonce = StringUtils.hasText(awsEc2.getNonce()) ? Nonce.provided(awsEc2.getNonce().toCharArray()) - : Nonce.generated(); - - AwsEc2AuthenticationOptions authenticationOptions = AwsEc2AuthenticationOptions.builder().role(awsEc2.getRole()) // - .path(awsEc2.getAwsEc2Path()) // - .nonce(nonce) // - .identityDocumentUri(awsEc2.getIdentityDocument()) // - .build(); - - return new AwsEc2Authentication(authenticationOptions, this.restOperations, this.externalRestOperations); - } - - ClientAuthentication awsIamAuthentication(VaultProperties vaultProperties) { - - AwsIamProperties awsIam = vaultProperties.getAwsIam(); - - AwsIamAuthenticationOptionsBuilder builder = AwsIamAuthenticationOptions.builder(); - AwsCredentialsProvider credentialsProvider = AwsCredentialProvider.getAwsCredentialsProvider(); - - if (StringUtils.hasText(awsIam.getRegion())) { - builder.region(Region.of(awsIam.getRegion())); - } - - if (StringUtils.hasText(awsIam.getRole())) { - builder.role(awsIam.getRole()); - } - - if (StringUtils.hasText(awsIam.getServerName())) { - builder.serverName(awsIam.getServerName()); - } - - if (awsIam.getEndpointUri() != null) { - builder.endpointUri(awsIam.getEndpointUri()); - } - - builder.path(awsIam.getAwsPath()) // - .credentialsProvider(credentialsProvider); - - AwsIamAuthenticationOptions options = builder.credentialsProvider(credentialsProvider).build(); - - return new AwsIamAuthentication(options, this.restOperations); - } - - private ClientAuthentication azureMsiAuthentication(VaultProperties vaultProperties) { - - AzureMsiProperties azureMsi = vaultProperties.getAzureMsi(); - - Assert.hasText(azureMsi.getRole(), "Azure role (spring.cloud.vault.azure-msi.role) must not be empty"); - - AzureMsiAuthenticationOptions options = AzureMsiAuthenticationOptions.builder() // - .role(azureMsi.getRole()).path(azureMsi.getAzurePath()) // - .instanceMetadataUri(azureMsi.getMetadataService()) // - .identityTokenServiceUri(azureMsi.getIdentityTokenService()) // - .build(); - - return new AzureMsiAuthentication(options, this.restOperations, this.externalRestOperations); - } - - private ClientAuthentication cubbyholeAuthentication() { - - Assert.hasText(this.vaultProperties.getToken(), - "Initial Token (spring.cloud.vault.token) for Cubbyhole authentication must not be empty"); - - CubbyholeAuthenticationOptions options = CubbyholeAuthenticationOptions.builder() // - .wrapped() // - .initialToken(VaultToken.of(this.vaultProperties.getToken())) // - .build(); - - return new CubbyholeAuthentication(options, this.restOperations); - } - - private ClientAuthentication gcpGceAuthentication(VaultProperties vaultProperties) { - - VaultProperties.GcpGceProperties gcp = vaultProperties.getGcpGce(); - - Assert.hasText(gcp.getRole(), "Role (spring.cloud.vault.gcp-gce.role) must not be empty"); - - GcpComputeAuthenticationOptionsBuilder builder = GcpComputeAuthenticationOptions.builder() - .path(gcp.getGcpPath()).role(gcp.getRole()); - - if (StringUtils.hasText(gcp.getServiceAccount())) { - builder.serviceAccount(gcp.getServiceAccount()); - } - - return new GcpComputeAuthentication(builder.build(), this.restOperations, this.externalRestOperations); - } - - private ClientAuthentication gcpIamAuthentication(VaultProperties vaultProperties) { - - if (googleCredentialPresent) { - return GcpIamAuthenticationFactory.create(vaultProperties, this.restOperations); - } - - if (googleCredentialsPresent) { - return GcpIamCredentialsAuthenticationFactory.create(vaultProperties, this.restOperations); - } - - throw new IllegalStateException( - "Cannot create authentication mechanism for GCP IAM. This method requires one of the following dependencies: google-auth-library-oauth2-http or google-api-client (deprecated)."); - } - - private ClientAuthentication kubernetesAuthentication(VaultProperties vaultProperties) { - - VaultProperties.KubernetesProperties kubernetes = vaultProperties.getKubernetes(); - - Assert.hasText(kubernetes.getRole(), "Role (spring.cloud.vault.kubernetes.role) must not be empty"); - Assert.hasText(kubernetes.getServiceAccountTokenFile(), - "Service account token file (spring.cloud.vault.kubernetes.service-account-token-file) must not be empty"); - - KubernetesAuthenticationOptions options = KubernetesAuthenticationOptions.builder() - .path(kubernetes.getKubernetesPath()).role(kubernetes.getRole()) - .jwtSupplier(new KubernetesServiceAccountTokenFile(kubernetes.getServiceAccountTokenFile())).build(); - - return new KubernetesAuthentication(options, this.restOperations); - } - - private ClientAuthentication pcfAuthentication(VaultProperties vaultProperties) { - - VaultProperties.PcfProperties pcfProperties = vaultProperties.getPcf(); - - Assert.isTrue(ClassUtils.isPresent("org.bouncycastle.crypto.signers.PSSSigner", getClass().getClassLoader()), - "BouncyCastle (bcpkix-jdk15on) must be on the classpath"); - Assert.hasText(pcfProperties.getRole(), "Role (spring.cloud.vault.pcf.role) must not be empty"); - - PcfAuthenticationOptions.PcfAuthenticationOptionsBuilder builder = PcfAuthenticationOptions.builder() - .role(pcfProperties.getRole()).path(pcfProperties.getPcfPath()); - - if (pcfProperties.getInstanceCertificate() != null) { - builder.instanceCertificate(new ResourceCredentialSupplier(pcfProperties.getInstanceCertificate())); - } - - if (pcfProperties.getInstanceKey() != null) { - builder.instanceKey(new ResourceCredentialSupplier(pcfProperties.getInstanceKey())); - } - - return new PcfAuthentication(builder.build(), this.restOperations); - } - - private ClientAuthentication certificateAuthentication(VaultProperties vaultProperties) { - - ClientCertificateAuthenticationOptions options = ClientCertificateAuthenticationOptions.builder() - .path(vaultProperties.getSsl().getCertAuthPath()).build(); - - return new ClientCertificateAuthentication(options, this.restOperations); - } - - private ClientAuthentication tokenAuthentication(VaultProperties vaultProperties) { - - if (StringUtils.hasText(vaultProperties.getToken())) { - return new TokenAuthentication(vaultProperties.getToken()); - } - - Path vaultTokenPath = Paths.get(SystemProperties.get("user.home"), ".vault-token"); - - if (Files.exists(vaultTokenPath)) { - try { - return new TokenAuthentication(new String(Files.readAllBytes(vaultTokenPath), UTF_8)); - } - catch (IOException ex) { - throw new IllegalStateException(String.format("Could not retrieve vault token from %s", vaultTokenPath), - ex); - } - } - else { - throw new IllegalStateException( - "Cannot create authentication mechanism for TOKEN. This method requires either a Token (spring.cloud.vault.token) or a token file at ~/.vault-token."); - } - } - - private static class AwsCredentialProvider { - - private static AwsCredentialsProvider getAwsCredentialsProvider() { - - DefaultCredentialsProvider backingCredentialsProvider = DefaultCredentialsProvider.create(); - - // Eagerly fetch credentials preventing lag during the first, actual login. - AwsCredentials firstAccess = backingCredentialsProvider.resolveCredentials(); - - AtomicReference once = new AtomicReference<>(firstAccess); - - return new AwsCredentialsProvider() { - - @Override - public AwsCredentials resolveCredentials() { - - if (once.compareAndSet(firstAccess, null)) { - return firstAccess; - } - - return backingCredentialsProvider.resolveCredentials(); - } - - }; - } - - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ConditionalOnAuthentication.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ConditionalOnAuthentication.java deleted file mode 100644 index f8d3cc1d..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ConditionalOnAuthentication.java +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.lang.annotation.Documented; -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.context.annotation.Conditional; - -/** - * {@link Conditional @Conditional} that only matches when no authentication is configured - * (i.e. {@code spring.cloud.vault.authentication=NONE}). - * - * @author Mark Paluch - * @since 2.2.2 - */ -@Retention(RetentionPolicy.RUNTIME) -@Target({ ElementType.TYPE, ElementType.METHOD }) -@Documented -@ConditionalOnExpression("!'NONE'.equalsIgnoreCase('${spring.cloud.vault.authentication}')") -@interface ConditionalOnAuthentication { - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DefaultRestTemplateFactory.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DefaultRestTemplateFactory.java deleted file mode 100644 index 98aa8bb9..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DefaultRestTemplateFactory.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.function.Consumer; -import java.util.function.Function; - -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.lang.Nullable; -import org.springframework.vault.client.RestTemplateBuilder; -import org.springframework.vault.client.RestTemplateFactory; -import org.springframework.web.client.RestTemplate; - -/** - * Default {@link RestTemplateFactory} implementation. - * - * @author Mark Paluch - * @since 3.0 - */ -class DefaultRestTemplateFactory implements RestTemplateFactory { - - private final ClientHttpRequestFactory requestFactory; - - private final Function builderFunction; - - DefaultRestTemplateFactory(ClientHttpRequestFactory requestFactory, - Function builderFunction) { - this.requestFactory = requestFactory; - this.builderFunction = builderFunction; - } - - @Override - public RestTemplate create(@Nullable Consumer customizer) { - - RestTemplateBuilder builder = this.builderFunction.apply(this.requestFactory); - - if (customizer != null) { - customizer.accept(builder); - } - - return builder.build(); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DefaultSecretBackendConfigurer.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DefaultSecretBackendConfigurer.java deleted file mode 100644 index de74ce6d..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DefaultSecretBackendConfigurer.java +++ /dev/null @@ -1,176 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.List; -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.vault.core.lease.domain.RequestedSecret; -import org.springframework.vault.core.lease.domain.RequestedSecret.Mode; -import org.springframework.vault.core.util.PropertyTransformer; -import org.springframework.vault.core.util.PropertyTransformers; - -/** - * Default {@link SecretBackendConfigurer} implementation that exposes its configuration - * through {@link PropertySourceLocatorConfiguration}. - * - * @author Mark Paluch - */ -class DefaultSecretBackendConfigurer implements SecretBackendConfigurer, PropertySourceLocatorConfiguration { - - private final Map secretBackends = new LinkedHashMap<>(); - - private boolean registerDefaultKeyValueSecretBackends = false; - - private boolean registerDefaultDiscoveredSecretBackends = false; - - @Override - public SecretBackendConfigurer add(String path) { - - Assert.hasLength(path, "Path must not be empty"); - - return add(path, PropertyTransformers.noop()); - } - - @Override - public SecretBackendConfigurer add(String path, PropertyTransformer propertyTransformer) { - - Assert.hasLength(path, "Path must not be empty"); - Assert.notNull(propertyTransformer, "PropertyTransformer must not be null"); - - return add(createMetadata(path, propertyTransformer)); - } - - private SimpleSecretBackendMetadata createMetadata(String path, PropertyTransformer propertyTransformer) { - return new SimpleSecretBackendMetadata(path, propertyTransformer); - } - - @Override - public SecretBackendConfigurer add(SecretBackendMetadata metadata) { - - Assert.notNull(metadata, "SecretBackendMetadata must not be null"); - - this.secretBackends.put(metadata.getPath(), metadata); - - return this; - } - - @Override - public SecretBackendConfigurer add(RequestedSecret requestedSecret) { - - Assert.notNull(requestedSecret, "RequestedSecret must not be null"); - - return add(requestedSecret, PropertyTransformers.noop()); - } - - @Override - public SecretBackendConfigurer add(RequestedSecret requestedSecret, PropertyTransformer propertyTransformer) { - - Assert.notNull(requestedSecret, "RequestedSecret must not be null"); - Assert.notNull(propertyTransformer, "PropertyTransformer must not be null"); - - this.secretBackends.put(requestedSecret.getPath(), new SimpleLeasingSecretBackendMetadata( - createMetadata(requestedSecret.getPath(), propertyTransformer), requestedSecret.getMode())); - - return this; - } - - @Override - - public SecretBackendConfigurer registerDefaultKeyValueSecretBackends(boolean registerDefault) { - this.registerDefaultKeyValueSecretBackends = registerDefault; - - return this; - } - - @Override - public SecretBackendConfigurer registerDefaultDiscoveredSecretBackends(boolean registerDefault) { - - this.registerDefaultDiscoveredSecretBackends = registerDefault; - - return this; - } - - public boolean isRegisterDefaultKeyValueSecretBackends() { - return this.registerDefaultKeyValueSecretBackends; - } - - public boolean isRegisterDefaultDiscoveredSecretBackends() { - return this.registerDefaultDiscoveredSecretBackends; - } - - @Override - public List getSecretBackends() { - return new ArrayList<>(this.secretBackends.values()); - } - - private static class SimpleSecretBackendMetadata implements SecretBackendMetadata { - - private final String path; - - private final PropertyTransformer propertyTransformer; - - SimpleSecretBackendMetadata(String path, PropertyTransformer propertyTransformer) { - this.path = path; - this.propertyTransformer = propertyTransformer; - } - - @Override - public String getName() { - return String.format("Context backend: %s", this.path); - } - - @Override - public String getPath() { - return this.path; - } - - @Override - public PropertyTransformer getPropertyTransformer() { - return this.propertyTransformer; - } - - @Override - public Map getVariables() { - return Collections.singletonMap("path", this.path); - } - - } - - private static class SimpleLeasingSecretBackendMetadata extends SecretBackendMetadataWrapper - implements LeasingSecretBackendMetadata { - - private final Mode mode; - - SimpleLeasingSecretBackendMetadata(SecretBackendMetadata delegate, Mode mode) { - - super(delegate); - this.mode = mode; - } - - @Override - public Mode getLeaseMode() { - return this.mode; - } - - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DefaultWebClientFactory.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DefaultWebClientFactory.java deleted file mode 100644 index 602f13ca..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DefaultWebClientFactory.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.function.Consumer; -import java.util.function.Function; - -import org.springframework.http.client.reactive.ClientHttpConnector; -import org.springframework.lang.Nullable; -import org.springframework.vault.client.WebClientBuilder; -import org.springframework.vault.client.WebClientFactory; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * Default implementation of {@link WebClientFactory}. - * - * @author Mark Paluch - * @since 3.0 - */ -class DefaultWebClientFactory implements WebClientFactory { - - private final ClientHttpConnector connector; - - private final Function builderFunction; - - DefaultWebClientFactory(ClientHttpConnector connector, - Function builderFunction) { - this.connector = connector; - this.builderFunction = builderFunction; - } - - @Override - public WebClient create(@Nullable Consumer customizer) { - - WebClientBuilder builder = this.builderFunction.apply(this.connector); - - if (customizer != null) { - customizer.accept(builder); - } - - return builder.build(); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DiscoveryClientVaultBootstrapConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DiscoveryClientVaultBootstrapConfiguration.java deleted file mode 100644 index 11f8353e..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DiscoveryClientVaultBootstrapConfiguration.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.EnableDiscoveryClient; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.vault.client.VaultEndpointProvider; - -/** - * {@link org.springframework.cloud.bootstrap.BootstrapConfiguration} providing a - * {@link VaultEndpointProvider} using {@link DiscoveryClient}. - * - * @author Mark Paluch - * @since 1.1 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty("spring.cloud.vault.discovery.enabled") -@EnableConfigurationProperties(VaultProperties.class) -@Order(Ordered.LOWEST_PRECEDENCE - 2) -@EnableDiscoveryClient -@Import(UtilAutoConfiguration.class) -public class DiscoveryClientVaultBootstrapConfiguration { - - private final VaultProperties vaultProperties; - - private final VaultConfiguration configuration; - - public DiscoveryClientVaultBootstrapConfiguration(VaultProperties vaultProperties) { - this.vaultProperties = vaultProperties; - this.configuration = new VaultConfiguration(vaultProperties); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true) - public VaultServiceInstanceProvider vaultServerInstanceProvider(DiscoveryClient discoveryClient) { - return new DiscoveryClientVaultServiceInstanceProvider(discoveryClient); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true) - public VaultEndpointProvider vaultEndpointProvider(VaultServiceInstanceProvider instanceProvider) { - - return () -> { - - String serviceId = this.vaultProperties.getDiscovery().getServiceId(); - ServiceInstance server = instanceProvider.getVaultServerInstance(serviceId); - - return this.configuration.createVaultEndpoint(server); - }; - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DiscoveryClientVaultServiceInstanceProvider.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DiscoveryClientVaultServiceInstanceProvider.java deleted file mode 100644 index 1e3d1822..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/DiscoveryClientVaultServiceInstanceProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; - -/** - * Provider for {@link ServiceInstance} to look up the Vault service. - * - * @author Mark Paluch - * @since 1.1 - */ -public class DiscoveryClientVaultServiceInstanceProvider implements VaultServiceInstanceProvider { - - private static final Log log = LogFactory.getLog(DiscoveryClientVaultServiceInstanceProvider.class); - - private final DiscoveryClient client; - - public DiscoveryClientVaultServiceInstanceProvider(DiscoveryClient client) { - this.client = client; - } - - @Override - public ServiceInstance getVaultServerInstance(String serviceId) { - - log.debug("Locating Vault server (" + serviceId + ") via discovery"); - - List instances = this.client.getInstances(serviceId); - - if (instances.isEmpty()) { - throw new IllegalStateException("No instances found of Vault server (" + serviceId + ")"); - } - - ServiceInstance instance = instances.get(0); - - log.debug("Located Vault server (" + serviceId + ") via discovery: " + instance); - - return instance; - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/GcpIamAuthenticationFactory.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/GcpIamAuthenticationFactory.java deleted file mode 100644 index 609c8b43..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/GcpIamAuthenticationFactory.java +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright 2020-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.Base64; - -import com.google.api.client.googleapis.auth.oauth2.GoogleCredential; - -import org.springframework.cloud.vault.config.VaultProperties.GcpIamProperties; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.GcpCredentialSupplier; -import org.springframework.vault.authentication.GcpIamAuthentication; -import org.springframework.vault.authentication.GcpIamAuthenticationOptions; -import org.springframework.vault.authentication.GcpIamAuthenticationOptions.GcpIamAuthenticationOptionsBuilder; -import org.springframework.web.client.RestOperations; - -/** - * Utility to create {@link GcpIamAuthentication} for the IAM authentication method. - * - * @author Mark Paluch - * @since 3.0.2 - */ -final class GcpIamAuthenticationFactory { - - private GcpIamAuthenticationFactory() { - } - - static ClientAuthentication create(VaultProperties vaultProperties, RestOperations restOperations) { - - VaultProperties.GcpIamProperties gcp = vaultProperties.getGcpIam(); - - Assert.hasText(gcp.getRole(), "Role (spring.cloud.vault.gcp-iam.role) must not be empty"); - - GcpIamAuthenticationOptionsBuilder builder = GcpIamAuthenticationOptions.builder().path(gcp.getGcpPath()) - .role(gcp.getRole()).jwtValidity(gcp.getJwtValidity()); - - if (StringUtils.hasText(gcp.getProjectId())) { - builder.projectId(gcp.getProjectId()); - } - - if (StringUtils.hasText(gcp.getServiceAccountId())) { - builder.serviceAccountId(gcp.getServiceAccountId()); - } - - GcpCredentialSupplier supplier = () -> getGoogleCredential(gcp); - builder.credential(supplier.get()); - - GcpIamAuthenticationOptions options = builder.build(); - - return new GcpIamAuthentication(options, restOperations); - } - - private static GoogleCredential getGoogleCredential(GcpIamProperties gcp) throws IOException { - - VaultProperties.GcpCredentials credentialProperties = gcp.getCredentials(); - if (credentialProperties.getLocation() != null) { - return GoogleCredential.fromStream(credentialProperties.getLocation().getInputStream()); - } - - if (StringUtils.hasText(credentialProperties.getEncodedKey())) { - return GoogleCredential.fromStream( - new ByteArrayInputStream(Base64.getDecoder().decode(credentialProperties.getEncodedKey()))); - } - - return GoogleCredential.getApplicationDefault(); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/GcpIamCredentialsAuthenticationFactory.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/GcpIamCredentialsAuthenticationFactory.java deleted file mode 100644 index 98b4cd96..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/GcpIamCredentialsAuthenticationFactory.java +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright 2020-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.io.ByteArrayInputStream; -import java.io.IOException; -import java.util.Base64; - -import com.google.auth.oauth2.GoogleCredentials; - -import org.springframework.cloud.vault.config.VaultProperties.GcpIamProperties; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.GcpIamCredentialsAuthentication; -import org.springframework.vault.authentication.GcpIamCredentialsAuthenticationOptions; -import org.springframework.vault.authentication.GcpIamCredentialsAuthenticationOptions.GcpIamCredentialsAuthenticationOptionsBuilder; -import org.springframework.vault.authentication.GoogleCredentialsSupplier; -import org.springframework.web.client.RestOperations; - -/** - * Utility to create {@link GcpIamCredentialsAuthentication} for the IAM Credentials - * authentication method. - * - * @author Mark Paluch - * @since 3.0.2 - */ -final class GcpIamCredentialsAuthenticationFactory { - - private GcpIamCredentialsAuthenticationFactory() { - } - - static ClientAuthentication create(VaultProperties vaultProperties, RestOperations restOperations) { - - GcpIamProperties gcp = vaultProperties.getGcpIam(); - - Assert.hasText(gcp.getRole(), "Role (spring.cloud.vault.gcp-iam.role) must not be empty"); - - GcpIamCredentialsAuthenticationOptionsBuilder builder = GcpIamCredentialsAuthenticationOptions.builder() - .path(gcp.getGcpPath()).role(gcp.getRole()).jwtValidity(gcp.getJwtValidity()); - - if (StringUtils.hasText(gcp.getServiceAccountId())) { - builder.serviceAccountId(gcp.getServiceAccountId()); - } - - GoogleCredentialsSupplier supplier = () -> getGoogleCredential(gcp); - builder.credentials(supplier.get()); - - GcpIamCredentialsAuthenticationOptions options = builder.build(); - - return new GcpIamCredentialsAuthentication(options, restOperations); - } - - private static GoogleCredentials getGoogleCredential(GcpIamProperties gcp) throws IOException { - - VaultProperties.GcpCredentials credentialProperties = gcp.getCredentials(); - if (credentialProperties.getLocation() != null) { - return GoogleCredentials.fromStream(credentialProperties.getLocation().getInputStream()); - } - - if (StringUtils.hasText(credentialProperties.getEncodedKey())) { - return GoogleCredentials.fromStream( - new ByteArrayInputStream(Base64.getDecoder().decode(credentialProperties.getEncodedKey()))); - } - - return GoogleCredentials.getApplicationDefault(); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/HealthBuilderDelegate.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/HealthBuilderDelegate.java deleted file mode 100644 index f46ca14d..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/HealthBuilderDelegate.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.util.StringUtils; -import org.springframework.vault.support.VaultHealth; - -/** - * Common delegate to transport health properties into the Health actuator - * {@link Health.Builder}. - * - * @author Mark Paluch - * @since 2.2 - */ -final class HealthBuilderDelegate { - - private HealthBuilderDelegate() { - } - - static void contributeToHealth(VaultHealth healthResponse, Health.Builder builder) { - - if (!healthResponse.isInitialized()) { - builder.down().withDetail("state", "Vault uninitialized"); - } - else if (healthResponse.isSealed()) { - builder.down().withDetail("state", "Vault sealed"); - } - else if (healthResponse.isStandby()) { - builder.up().withDetail("state", "Vault in standby"); - } - else if (healthResponse.isPerformanceStandby()) { - builder.up().withDetail("state", "Vault in performance standby"); - } - else if (healthResponse.isRecoveryReplicationSecondary()) { - builder.up().withDetail("state", "Vault in recovery replication secondary mode"); - } - else { - builder.up(); - } - - if (StringUtils.hasText(healthResponse.getVersion())) { - builder.withDetail("version", healthResponse.getVersion()); - } - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/KeyValueSecretBackendMetadata.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/KeyValueSecretBackendMetadata.java deleted file mode 100644 index 144576bc..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/KeyValueSecretBackendMetadata.java +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.LinkedHashSet; -import java.util.List; -import java.util.Map; -import java.util.Map.Entry; -import java.util.Set; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.vault.core.util.PropertyTransformer; -import org.springframework.vault.core.util.PropertyTransformers; - -/** - * {@link SecretBackendMetadata} for the {@code kv} (key-value) secret backend. - * - * @author Mark Paluch - * @since 2.0 - */ -public class KeyValueSecretBackendMetadata extends SecretBackendMetadataSupport implements SecretBackendMetadata { - - private final String path; - - private final PropertyTransformer propertyTransformer; - - KeyValueSecretBackendMetadata(String path) { - this(path, PropertyTransformers.noop()); - } - - private KeyValueSecretBackendMetadata(String path, PropertyTransformer propertyTransformer) { - - Assert.hasText(path, "Secret backend path must not be empty"); - Assert.notNull(propertyTransformer, "PropertyTransformer must not be null"); - - this.path = path; - this.propertyTransformer = propertyTransformer; - } - - /** - * Create a {@link SecretBackendMetadata} for the {@code kv} secret backend given a - * {@code secretBackendPath} and {@code key}. Use plain mount and key paths. The - * required {@code data} segment is added by this method. - * @param secretBackendPath the secret backend mount path without leading/trailing - * slashes and without the {@code data} path segment, must not be empty or - * {@literal null}. - * @param key the key within the secret backend. May contain slashes but not - * leading/trailing slashes, must not be empty or {@literal null}. - * @return the {@link SecretBackendMetadata} - */ - public static SecretBackendMetadata create(String secretBackendPath, String key) { - - Assert.hasText(secretBackendPath, "Secret backend path must not be null or empty"); - Assert.hasText(key, "Key must not be null or empty"); - - return create(String.format("%s/%s", secretBackendPath, key), UnwrappingPropertyTransformer.unwrap("data")); - } - - /** - * Create a {@link SecretBackendMetadata} for the {@code kv} secret backend given a - * {@code path}. - * @param path the relative path of the secret. slashes, must not be empty or - * {@literal null}. - * @return the {@link SecretBackendMetadata} - */ - public static SecretBackendMetadata create(String path) { - return new KeyValueSecretBackendMetadata(path, PropertyTransformers.noop()); - } - - /** - * Create a {@link SecretBackendMetadata} for the {@code kv} secret backend given a - * {@code path}. - * @param path the relative path of the secret. slashes, must not be empty or - * {@literal null}. - * @param propertyTransformer property transformer. - * @return the {@link SecretBackendMetadata} - */ - public static SecretBackendMetadata create(String path, PropertyTransformer propertyTransformer) { - return new KeyValueSecretBackendMetadata(path, propertyTransformer); - } - - /** - * Build a list of context paths from application name and the active profile names. - * Application name and profiles support multiple (comma-separated) values. - * @param properties the key-value backend properties. - * @param profiles active application profiles. - * @return list of context paths. - */ - public static List buildContexts(VaultKeyValueBackendPropertiesSupport properties, List profiles) { - - String appName = properties.getApplicationName(); - - String defaultContext = properties.getDefaultContext(); - Set contexts = new LinkedHashSet<>( - buildContexts(defaultContext, profiles, properties.getProfileSeparator())); - - for (String applicationName : StringUtils.commaDelimitedListToSet(appName)) { - contexts.addAll(buildContexts(applicationName, profiles, properties.getProfileSeparator())); - } - - List result = new ArrayList<>(contexts); - - Collections.reverse(result); - - return result; - } - - /** - * Create a list of context names from a combination of application name and - * application name with profile name. Using an empty application name will return an - * empty list. - * @param applicationName the application name. May be empty. - * @param profiles active application profiles. - * @param profileSeparator profile separator character between application name and - * profile name. - * @return list of context names. - */ - public static List buildContexts(String applicationName, List profiles, String profileSeparator) { - - if (!StringUtils.hasText(applicationName)) { - return Collections.emptyList(); - } - - List contexts = new ArrayList<>(profiles.size() + 1); - contexts.add(applicationName); - - for (String profile : profiles) { - - if (!StringUtils.hasText(profile)) { - continue; - } - - String contextName = applicationName + profileSeparator + profile.trim(); - - if (!contexts.contains(contextName)) { - contexts.add(contextName); - } - } - - return contexts; - } - - @Override - public String getPath() { - return this.path; - } - - @Override - public PropertyTransformer getPropertyTransformer() { - return this.propertyTransformer; - } - - /** - * {@link PropertyTransformer} that strips a prefix from property names. - */ - static final class UnwrappingPropertyTransformer implements PropertyTransformer { - - private final String prefixToStrip; - - private UnwrappingPropertyTransformer(String prefixToStrip) { - - Assert.notNull(prefixToStrip, "Property name prefix must not be null"); - - this.prefixToStrip = prefixToStrip; - } - - /** - * Create a new {@link PropertyTransformers.KeyPrefixPropertyTransformer} that - * adds a prefix to each key name. - * @param propertyNamePrefix the property name prefix to be added in front of each - * property name, must not be {@literal null}. - * @return a new {@link PropertyTransformers.KeyPrefixPropertyTransformer} that - * adds a prefix to each key name. - */ - public static PropertyTransformer unwrap(String propertyNamePrefix) { - return new UnwrappingPropertyTransformer(propertyNamePrefix); - } - - @Override - public Map transformProperties(Map input) { - - Map target = new LinkedHashMap<>(input.size(), 1); - - for (Entry entry : input.entrySet()) { - - if (entry.getKey().startsWith(this.prefixToStrip + ".")) { - target.put(entry.getKey().substring(this.prefixToStrip.length() + 1), entry.getValue()); - } - else { - target.put(entry.getKey(), entry.getValue()); - } - } - - return target; - } - - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/LeasingSecretBackendMetadata.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/LeasingSecretBackendMetadata.java deleted file mode 100644 index 4f6eb859..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/LeasingSecretBackendMetadata.java +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.vault.core.lease.SecretLeaseContainer; -import org.springframework.vault.core.lease.domain.RequestedSecret; -import org.springframework.vault.core.lease.domain.RequestedSecret.Mode; - -/** - * Lease extension to {@link SecretBackendMetadata} providing a - * {@link org.springframework.vault.core.lease.domain.RequestedSecret.Mode lease mode}. - * - * @author Mark Paluch - * @since 1.1 - * @see org.springframework.vault.core.lease.domain.RequestedSecret - */ -public interface LeasingSecretBackendMetadata extends SecretBackendMetadata { - - /** - * Return the lease mode of this secret backend. - *

- * Lease mode is considered only by lease-aware property sources. - * @return the lease mode of this secret backend. - * @since 1.1 - */ - Mode getLeaseMode(); - - /** - * Callback method before registering a {@link RequestedSecret secret} with - * {@link SecretLeaseContainer}. Registering a {@code before} callback allows event - * consumption before the secrets are visible in the associated property source. - * @param secret the requested secret. - * @param container the lease container that was used to request the secret. - * @since 3.0 - */ - default void beforeRegistration(RequestedSecret secret, SecretLeaseContainer container) { - } - - /** - * Callback method after registering a {@link RequestedSecret secret} with - * {@link SecretLeaseContainer}. Registering a {@code after} callback allows event - * consumption after the secrets are visible in the associated property source. Note - * that this callback does not necessarily guarantee notification of the initial - * secrets retrieval. - * @param secret the requested secret. - * @param container the lease container that was used to request the secret. - * @since 3.0 - */ - default void afterRegistration(RequestedSecret secret, SecretLeaseContainer container) { - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/LeasingVaultPropertySourceLocator.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/LeasingVaultPropertySourceLocator.java deleted file mode 100644 index 2c58292a..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/LeasingVaultPropertySourceLocator.java +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.concurrent.atomic.AtomicReference; - -import org.springframework.core.PriorityOrdered; -import org.springframework.core.env.PropertySource; -import org.springframework.util.Assert; -import org.springframework.vault.VaultException; -import org.springframework.vault.core.env.LeaseAwareVaultPropertySource; -import org.springframework.vault.core.lease.SecretLeaseContainer; -import org.springframework.vault.core.lease.domain.RequestedSecret; -import org.springframework.vault.core.lease.event.LeaseErrorListener; - -/** - * Extension to {@link LeasingVaultPropertySourceLocator} that creates - * {@link LeaseAwareVaultPropertySource}s. - * - * @author Mark Paluch - * @see LeaseAwareVaultPropertySource - */ -@Deprecated -class LeasingVaultPropertySourceLocator extends VaultPropertySourceLocatorSupport implements PriorityOrdered { - - private final SecretLeaseContainer secretLeaseContainer; - - private final VaultProperties properties; - - /** - * Creates a new {@link LeasingVaultPropertySourceLocator}. - * @param properties must not be {@literal null}. - * @param propertySourceLocatorConfiguration must not be {@literal null}. - * @param secretLeaseContainer must not be {@literal null}. - * @since 1.1 - */ - LeasingVaultPropertySourceLocator(VaultProperties properties, - PropertySourceLocatorConfiguration propertySourceLocatorConfiguration, - SecretLeaseContainer secretLeaseContainer) { - - super("vault", propertySourceLocatorConfiguration); - - Assert.notNull(secretLeaseContainer, "SecretLeaseContainer must not be null"); - Assert.notNull(properties, "VaultProperties must not be null"); - - this.secretLeaseContainer = secretLeaseContainer; - this.properties = properties; - } - - @Override - public int getOrder() { - return this.properties.getConfig().getOrder(); - } - - /** - * Create {@link VaultPropertySource} initialized with a {@link SecretBackendMetadata} - * . - * @param accessor the {@link SecretBackendMetadata}. - * @return the {@link VaultPropertySource} to use. - */ - protected PropertySource createVaultPropertySource(SecretBackendMetadata accessor) { - - RequestedSecret secret = getRequestedSecret(accessor); - - if (this.properties.isFailFast()) { - return createVaultPropertySourceFailFast(secret, accessor); - } - - return createVaultPropertySource(secret, accessor); - } - - private RequestedSecret getRequestedSecret(SecretBackendMetadata accessor) { - - if (accessor instanceof LeasingSecretBackendMetadata) { - - LeasingSecretBackendMetadata leasingBackend = (LeasingSecretBackendMetadata) accessor; - return RequestedSecret.from(leasingBackend.getLeaseMode(), accessor.getPath()); - } - - if (accessor instanceof KeyValueSecretBackendMetadata) { - return RequestedSecret.rotating(accessor.getPath()); - } - - return RequestedSecret.renewable(accessor.getPath()); - } - - /** - * Decorated {@link PropertySource} creation to catch and throw the first error that - * occurred during initial secret retrieval. - * @param secret the requested secret. - * @param accessor the metadata accessor. - * @return the property source for the {@link RequestedSecret}. - */ - private PropertySource createVaultPropertySourceFailFast(RequestedSecret secret, - SecretBackendMetadata accessor) { - - final AtomicReference errorRef = new AtomicReference<>(); - - LeaseErrorListener errorListener = (leaseEvent, exception) -> { - - if (leaseEvent.getSource() == secret) { - errorRef.compareAndSet(null, exception); - } - }; - - this.secretLeaseContainer.addErrorListener(errorListener); - try { - return createVaultPropertySource(secret, accessor); - } - finally { - this.secretLeaseContainer.removeLeaseErrorListener(errorListener); - - Exception exception = errorRef.get(); - if (exception != null) { - if (exception instanceof VaultException) { - throw (VaultException) exception; - } - throw new VaultException( - String.format("Cannot initialize PropertySource for secret at %s", secret.getPath()), - exception); - } - } - } - - private PropertySource createVaultPropertySource(RequestedSecret secret, SecretBackendMetadata accessor) { - - if (accessor instanceof LeasingSecretBackendMetadata) { - ((LeasingSecretBackendMetadata) accessor).beforeRegistration(secret, this.secretLeaseContainer); - } - - LeaseAwareVaultPropertySource propertySource = new LeaseAwareVaultPropertySource(accessor.getName(), - this.secretLeaseContainer, secret, accessor.getPropertyTransformer()); - - if (accessor instanceof LeasingSecretBackendMetadata) { - ((LeasingSecretBackendMetadata) accessor).afterRegistration(secret, this.secretLeaseContainer); - } - - return propertySource; - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/PropertyNameTransformer.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/PropertyNameTransformer.java deleted file mode 100644 index 923e6200..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/PropertyNameTransformer.java +++ /dev/null @@ -1,79 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.HashMap; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.vault.core.util.PropertyTransformer; - -/** - * {@link PropertyTransformer} to transform a {@link Map} of properties by applying key - * name translation. - * - *

- * Existing keys will be transformed to a target key name while retaining the original - * value. Key name translation will leave other, not specified key names untouched. - * - * @author Mark Paluch - */ -public class PropertyNameTransformer implements PropertyTransformer { - - private final Map nameMapping = new HashMap<>(); - - /** - * Create a new {@link PropertyNameTransformer}. - */ - public PropertyNameTransformer() { - } - - /** - * Adds a key name transformation by providing a {@code sourceKeyName} and a - * {@code targetKeyName}. - * @param sourceKeyName must not be empty or {@literal null}. - * @param targetKeyName must not be empty or {@literal null}. - */ - public void addKeyTransformation(String sourceKeyName, String targetKeyName) { - - Assert.hasText(sourceKeyName, "Source key name must not be empty"); - Assert.hasText(targetKeyName, "Target key name must not be empty"); - - this.nameMapping.put(sourceKeyName, targetKeyName); - } - - @Override - public Map transformProperties(Map input) { - - Map transformed = new LinkedHashMap<>(input.size(), 1); - - for (String key : input.keySet()) { - - String translatedKey = key; - - if (this.nameMapping.containsKey(key)) { - translatedKey = this.nameMapping.get(key); - } - - transformed.put(translatedKey, input.get(key)); - } - - return transformed; - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/PropertySourceLocatorConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/PropertySourceLocatorConfiguration.java deleted file mode 100644 index 3888f756..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/PropertySourceLocatorConfiguration.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collection; - -/** - * Configuration for a Vault - * {@link org.springframework.cloud.bootstrap.config.PropertySourceLocator}. - * - * @author Mark Paluch - * @since 1.1 - */ -public interface PropertySourceLocatorConfiguration { - - /** - * Return a {@link Collection} of {@link SecretBackendMetadata} to be instantiated as - * {@link org.springframework.core.env.PropertySource}. - * @return a {@link Collection} of {@link SecretBackendMetadata}. - */ - Collection getSecretBackends(); - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/PropertySourceLocatorConfigurationFactory.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/PropertySourceLocatorConfigurationFactory.java deleted file mode 100644 index 74204486..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/PropertySourceLocatorConfigurationFactory.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collection; -import java.util.List; - -/** - * Factory for {@link PropertySourceLocatorConfigurationFactory}. - * - * @author Mark Paluch - * @since 3.0 - */ -class PropertySourceLocatorConfigurationFactory { - - private final Collection configurers; - - private final Collection vaultSecretBackendDescriptors; - - private final Collection> factories; - - PropertySourceLocatorConfigurationFactory(Collection configurers, - Collection vaultSecretBackendDescriptors, - Collection> factories) { - this.configurers = configurers; - this.vaultSecretBackendDescriptors = vaultSecretBackendDescriptors; - this.factories = factories; - } - - /** - * Apply configuration through {@link VaultConfigurer}. - * @param keyValueBackends configured backend. - * @return the {@link PropertySourceLocatorConfiguration}. - */ - PropertySourceLocatorConfiguration getPropertySourceConfiguration( - VaultKeyValueBackendPropertiesSupport... keyValueBackends) { - - DefaultSecretBackendConfigurer secretBackendConfigurer = new DefaultSecretBackendConfigurer(); - - if (this.configurers.isEmpty()) { - secretBackendConfigurer.registerDefaultKeyValueSecretBackends(true) - .registerDefaultDiscoveredSecretBackends(true); - } - else { - - for (VaultConfigurer vaultConfigurer : this.configurers) { - vaultConfigurer.addSecretBackends(secretBackendConfigurer); - } - } - - if (secretBackendConfigurer.isRegisterDefaultKeyValueSecretBackends()) { - - for (VaultKeyValueBackendPropertiesSupport keyValueBackend : keyValueBackends) { - - if (!keyValueBackend.isEnabled()) { - continue; - } - - List contexts = KeyValueSecretBackendMetadata.buildContexts(keyValueBackend, - keyValueBackend.getProfiles()); - - for (String context : contexts) { - secretBackendConfigurer - .add(KeyValueSecretBackendMetadata.create(keyValueBackend.getBackend(), context)); - } - } - - Collection backendAccessors = SecretBackendFactories - .createSecretBackendMetadata(this.vaultSecretBackendDescriptors, this.factories); - - backendAccessors.forEach(secretBackendConfigurer::add); - } - - if (secretBackendConfigurer.isRegisterDefaultDiscoveredSecretBackends()) { - - Collection backendAccessors = SecretBackendFactories - .createSecretBackendMetadata(this.vaultSecretBackendDescriptors, this.factories); - - backendAccessors.forEach(secretBackendConfigurer::add); - } - - return secretBackendConfigurer; - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ReactiveDiscoveryClientVaultBootstrapConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ReactiveDiscoveryClientVaultBootstrapConfiguration.java deleted file mode 100644 index fce6cb5e..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ReactiveDiscoveryClientVaultBootstrapConfiguration.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import reactor.core.publisher.Flux; -import reactor.core.publisher.Mono; -import reactor.core.scheduler.Schedulers; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.cloud.commons.util.UtilAutoConfiguration; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.vault.client.ReactiveVaultEndpointProvider; -import org.springframework.vault.client.VaultEndpointProvider; -import org.springframework.vault.core.ReactiveVaultOperations; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * {@link org.springframework.cloud.bootstrap.BootstrapConfiguration} providing a - * {@link VaultEndpointProvider} using {@link DiscoveryClient}. - * - * @author Mark Paluch - * @since 1.1 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty("spring.cloud.vault.discovery.enabled") -@ConditionalOnExpression("${spring.cloud.vault.reactive.enabled:true}") -@ConditionalOnClass({ Flux.class, WebClient.class, ReactiveVaultOperations.class, ReactiveDiscoveryClient.class }) -@EnableConfigurationProperties(VaultProperties.class) -@Order(Ordered.LOWEST_PRECEDENCE - 5) -@Import(UtilAutoConfiguration.class) -public class ReactiveDiscoveryClientVaultBootstrapConfiguration { - - private final VaultProperties vaultProperties; - - private final VaultConfiguration configuration; - - public ReactiveDiscoveryClientVaultBootstrapConfiguration(VaultProperties vaultProperties) { - this.vaultProperties = vaultProperties; - this.configuration = new VaultConfiguration(vaultProperties); - } - - @Bean - @ConditionalOnMissingBean - @ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true) - public ReactiveVaultEndpointProvider reactiveVaultEndpointProvider( - ObjectProvider reactiveDiscoveryClients, - ObjectProvider endpointProviders) { - - ReactiveDiscoveryClient reactiveDiscoveryClient = reactiveDiscoveryClients.getIfAvailable(); - - if (reactiveDiscoveryClient != null) { - ReacvtiveDiscoveryClientVaultServiceInstanceProvider instanceProvider = new ReacvtiveDiscoveryClientVaultServiceInstanceProvider( - reactiveDiscoveryClient); - - return () -> Mono.defer(() -> { - - String serviceId = this.vaultProperties.getDiscovery().getServiceId(); - - return instanceProvider.getVaultServerInstance(serviceId).map(this.configuration::createVaultEndpoint); - }); - } - - VaultEndpointProvider endpointProvider = endpointProviders.getObject(); - - return () -> Mono.fromSupplier(endpointProvider::getVaultEndpoint).subscribeOn(Schedulers.boundedElastic()); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ReacvtiveDiscoveryClientVaultServiceInstanceProvider.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ReacvtiveDiscoveryClientVaultServiceInstanceProvider.java deleted file mode 100644 index f0ecdec3..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/ReacvtiveDiscoveryClientVaultServiceInstanceProvider.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import reactor.core.publisher.Mono; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; - -/** - * Provider for {@link ServiceInstance} to look up the Vault service. - * - * @author Mark Paluch - * @since 3.0 - */ -class ReacvtiveDiscoveryClientVaultServiceInstanceProvider { - - private static final Log log = LogFactory.getLog(ReacvtiveDiscoveryClientVaultServiceInstanceProvider.class); - - private final ReactiveDiscoveryClient client; - - ReacvtiveDiscoveryClientVaultServiceInstanceProvider(ReactiveDiscoveryClient client) { - this.client = client; - } - - Mono getVaultServerInstance(String serviceId) { - - log.debug("Locating Vault server (" + serviceId + ") via discovery"); - - return this.client.getInstances(serviceId).collectList().handle((instances, sink) -> { - - if (instances.isEmpty()) { - sink.error(new IllegalStateException("No instances found of Vault server (" + serviceId + ")")); - return; - } - - ServiceInstance instance = instances.get(0); - - log.debug("Located Vault server (" + serviceId + ") via discovery: " + instance); - - sink.next(instance); - }); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendConfigurer.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendConfigurer.java deleted file mode 100644 index 0e21cb7d..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendConfigurer.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.vault.core.lease.domain.RequestedSecret; -import org.springframework.vault.core.util.PropertyTransformer; - -/** - * Helps to configure {@link SecretBackendMetadata secret backends} with support for - * {@link PropertyTransformer property transformers}. - * - *

- * Assists configuration with a fluent style. This configurer allows configuration via - * context paths and direct registration of {@link SecretBackendMetadata}. - *

- * Use {@link #registerDefaultKeyValueSecretBackends(boolean)} to register default kv - * secret backend property sources and - * {@link #registerDefaultDiscoveredSecretBackends(boolean)} to register additional secret - * backend property sources such as MySQL and RabbitMQ. - * - * @author Mark Paluch - * @since 1.1 - * @see PropertyTransformer - * @see SecretBackendMetadata - */ -public interface SecretBackendConfigurer { - - /** - * Add a {@link SecretBackendMetadata} given its {@code path}. - * @param path must not be {@literal null} or empty. - * @return {@code this} {@link SecretBackendConfigurer}. - */ - SecretBackendConfigurer add(String path); - - /** - * Add a {@link SecretBackendMetadata} given its {@code path} and - * {@link PropertyTransformer}. - * @param path must not be {@literal null} or empty. - * @param propertyTransformer must not be {@literal null}. - * @return {@code this} {@link SecretBackendConfigurer}. - */ - SecretBackendConfigurer add(String path, PropertyTransformer propertyTransformer); - - /** - * Add a {@link SecretBackendMetadata}. - * @param metadata must not be {@literal null}. - * @return {@code this} {@link SecretBackendConfigurer}. - */ - SecretBackendConfigurer add(SecretBackendMetadata metadata); - - /** - * Add a {@link SecretBackendMetadata} given {@link RequestedSecret}. Property sources - * supporting leasing will derive lease renewal/rotation from - * {@link RequestedSecret.Mode}. - * @param requestedSecret must not be {@literal null} or empty. - * @return {@code this} {@link SecretBackendConfigurer}. - */ - SecretBackendConfigurer add(RequestedSecret requestedSecret); - - /** - * Add a {@link SecretBackendMetadata} given {@link RequestedSecret} and - * {@link PropertyTransformer}. Property sources supporting leasing will derive lease - * renewal/rotation from {@link RequestedSecret.Mode}. - * @param requestedSecret must not be {@literal null} or empty. - * @param propertyTransformer must not be {@literal null}. - * @return {@code this} {@link SecretBackendConfigurer}. - */ - SecretBackendConfigurer add(RequestedSecret requestedSecret, PropertyTransformer propertyTransformer); - - /** - * Register default key-value secret backend property sources. - * @param registerDefault {@literal true} to enable default kv secret backend - * registration. - * @return {@code this} {@link SecretBackendConfigurer}. - * @since 2.3.3 - */ - SecretBackendConfigurer registerDefaultKeyValueSecretBackends(boolean registerDefault); - - /** - * Register default discovered secret backend property sources from - * {@link SecretBackendMetadata} via {@link VaultSecretBackendDescriptor} beans. - * @param registerDefault {@literal true} to enable default discovered secret backend - * registration via {@link VaultSecretBackendDescriptor} beans. - * @return {@code this} {@link SecretBackendConfigurer}. - */ - SecretBackendConfigurer registerDefaultDiscoveredSecretBackends(boolean registerDefault); - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendFactories.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendFactories.java deleted file mode 100644 index 4a830f10..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendFactories.java +++ /dev/null @@ -1,80 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -/** - * Utility class to create {@link SecretBackendMetadata} from a - * {@link SecretBackendMetadataFactory}. - * - * @author Mark Paluch - */ -final class SecretBackendFactories { - - private static final Log log = LogFactory.getLog(SecretBackendFactories.class); - - private SecretBackendFactories() { - - } - - static Collection createSecretBackendMetadata( - Collection vaultSecretBackendDescriptors, - Collection> factories) { - - List accessors = new ArrayList<>(); - - for (VaultSecretBackendDescriptor vaultSecretBackendDescriptor : vaultSecretBackendDescriptors) { - - if (!vaultSecretBackendDescriptor.isEnabled()) { - continue; - } - - SecretBackendMetadata metadata = createSecretBackendMetadata(factories, vaultSecretBackendDescriptor); - - if (metadata == null) { - log.warn(String.format("Cannot create SecretBackendMetadata for %s", vaultSecretBackendDescriptor)); - continue; - } - - accessors.add(metadata); - } - - return accessors; - } - - private static SecretBackendMetadata createSecretBackendMetadata( - Collection> factories, - VaultSecretBackendDescriptor vaultSecretBackendDescriptor) { - - SecretBackendMetadata accessor = null; - for (SecretBackendMetadataFactory factory : factories) { - - if (factory.supports(vaultSecretBackendDescriptor)) { - accessor = factory.createMetadata(vaultSecretBackendDescriptor); - break; - } - } - return accessor; - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadata.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadata.java deleted file mode 100644 index 04180256..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadata.java +++ /dev/null @@ -1,62 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Map; - -import org.springframework.vault.core.util.PropertyTransformer; - -/** - * Interface specifying the API to obtain URL variables and optionally a - * {@link PropertyTransformer}. Typically used by {@link VaultPropertySource}. Supports - * ordering of implementations. - * - * @author Mark Paluch - * @see PropertyTransformer - * @see org.springframework.core.Ordered - * @see org.springframework.core.annotation.Order - */ -public interface SecretBackendMetadata { - - /** - * Return a readable name of this secret backend. - * @return the name of this secret backend. - */ - String getName(); - - /** - * Return the path of this secret backend. - * @return the path of this secret backend. - * @since 1.1 - */ - String getPath(); - - /** - * Return a {@link PropertyTransformer} to post-process properties retrieved from - * Vault. - * @return the property transformer. - * @see org.springframework.vault.core.util.PropertyTransformers - */ - PropertyTransformer getPropertyTransformer(); - - /** - * @return the URL template variables. URI variables should declare either - * {@code backend} and {@code key} or {@code path} properties. - */ - Map getVariables(); - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadataFactory.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadataFactory.java deleted file mode 100644 index f17dd472..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadataFactory.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.boot.context.config.ConfigDataLocationResolver; -import org.springframework.cloud.bootstrap.BootstrapConfiguration; -import org.springframework.context.ApplicationContext; - -/** - * Strategy interface to create {@link SecretBackendMetadata} from - * {@link VaultSecretBackendDescriptor} properties. Mainly for internal use within the - * framework. - * - *

- * Classes implementing this interface must implement - * {@link #supports(VaultSecretBackendDescriptor)} to determine whether a particular - * {@link VaultSecretBackendDescriptor} is supported by this implementation. If a - * {@link VaultSecretBackendDescriptor} instance is supported by the implementation, it - * must be able to create {@link SecretBackendMetadata}, see - * {@link #createMetadata(VaultSecretBackendDescriptor)}. - * - *

- * Typically implemented by secret backend providers that implement access to a particular - * backend using read operations. Objects implementing this interface can be discovered - * either from the {@link ApplicationContext} when using {@link BootstrapConfiguration} - * (deprecated since 3.0) or {@code spring.factories} when using - * {@link ConfigDataLocationResolver}. - * - * @param descriptor type. - * @author Mark Paluch - * @see SecretBackendMetadata - * @see LeasingSecretBackendMetadata - * @see VaultSecretBackendDescriptor - */ -public interface SecretBackendMetadataFactory { - - /** - * Converts a {@link VaultSecretBackendDescriptor} into a - * {@link SecretBackendMetadata}. - * @param backendDescriptor must not be {@literal null}. - * @return the {@link SecretBackendMetadata}. - * @see LeasingSecretBackendMetadata - */ - SecretBackendMetadata createMetadata(T backendDescriptor); - - /** - * Checks whether the {@link VaultSecretBackendDescriptor} is supported by this - * {@link SecretBackendMetadataFactory}. - * @param backendDescriptor must not be {@literal null}. - * @return {@literal true} if the given {@link VaultSecretBackendDescriptor} is - * supported. - */ - boolean supports(VaultSecretBackendDescriptor backendDescriptor); - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadataSupport.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadataSupport.java deleted file mode 100644 index 67cbd58c..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadataSupport.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; -import java.util.Map; - -import org.springframework.vault.core.util.PropertyTransformer; -import org.springframework.vault.core.util.PropertyTransformers; - -/** - * Support class for {@link SecretBackendMetadata} implementations. Implementing classes - * are required to implement {@link #getPath()} to derive name and variables from the - * path. - * - * @author Mark Paluch - * @since 1.1 - */ -public abstract class SecretBackendMetadataSupport implements SecretBackendMetadata { - - @Override - public String getName() { - return getPath(); - } - - @Override - public PropertyTransformer getPropertyTransformer() { - return PropertyTransformers.noop(); - } - - @Override - public Map getVariables() { - return Collections.singletonMap("path", getPath()); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadataWrapper.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadataWrapper.java deleted file mode 100644 index cd4bf30b..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/SecretBackendMetadataWrapper.java +++ /dev/null @@ -1,70 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.vault.core.util.PropertyTransformer; - -/** - * Provides a convenient implementation of the {@link SecretBackendMetadata} interface - * that can be subclassed to override specific methods. - *

- * This class implements the Wrapper or Decorator pattern. Methods default to calling - * through to the wrapped request object. - * - * @author Mark Paluch - * @since 1.1 - */ -public class SecretBackendMetadataWrapper implements SecretBackendMetadata { - - private final SecretBackendMetadata delegate; - - /** - * Create a new {@link SecretBackendMetadataWrapper} given - * {@link SecretBackendMetadata}. - * @param delegate must not be {@literal null}. - */ - public SecretBackendMetadataWrapper(SecretBackendMetadata delegate) { - - Assert.notNull(delegate, "SecretBackendMetadata delegate must not be null"); - - this.delegate = delegate; - } - - @Override - public String getName() { - return this.delegate.getName(); - } - - @Override - public String getPath() { - return this.delegate.getPath(); - } - - @Override - public PropertyTransformer getPropertyTransformer() { - return this.delegate.getPropertyTransformer(); - } - - @Override - public Map getVariables() { - return this.delegate.getVariables(); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/Secrets.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/Secrets.java deleted file mode 100644 index b4a25d1f..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/Secrets.java +++ /dev/null @@ -1,31 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Map; - -import org.springframework.vault.support.VaultResponseSupport; - -/** - * Value object that represents Vault secrets. {@link Secrets} contains metadata, lease - * details and a map of secret data. - * - * @author Mark Paluch - */ -public class Secrets extends VaultResponseSupport> { - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultAutoConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultAutoConfiguration.java deleted file mode 100644 index 0b390c8a..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultAutoConfiguration.java +++ /dev/null @@ -1,272 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Lazy; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.annotation.Order; -import org.springframework.core.task.AsyncTaskExecutor; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.scheduling.TaskScheduler; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.LifecycleAwareSessionManager; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.client.RestTemplateBuilder; -import org.springframework.vault.client.RestTemplateCustomizer; -import org.springframework.vault.client.RestTemplateFactory; -import org.springframework.vault.client.RestTemplateRequestCustomizer; -import org.springframework.vault.client.SimpleVaultEndpointProvider; -import org.springframework.vault.client.VaultEndpointProvider; -import org.springframework.vault.config.AbstractVaultConfiguration.ClientFactoryWrapper; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.core.VaultTemplate; -import org.springframework.vault.support.ClientOptions; -import org.springframework.vault.support.SslConfiguration; -import org.springframework.web.client.RestTemplate; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for Spring Vault support. - * - * @author Spencer Gibb - * @author Mark Paluch - * @since 3.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true) -@EnableConfigurationProperties(VaultProperties.class) -@Order(Ordered.LOWEST_PRECEDENCE - 5) -public class VaultAutoConfiguration { - - private final ConfigurableApplicationContext applicationContext; - - private final VaultProperties vaultProperties; - - private final VaultConfiguration configuration; - - private final VaultEndpointProvider endpointProvider; - - private final List customizers; - - private final List> requestCustomizers; - - public VaultAutoConfiguration(ConfigurableApplicationContext applicationContext, VaultProperties vaultProperties, - ObjectProvider endpointProvider, - ObjectProvider> customizers, - ObjectProvider>> requestCustomizers) { - - this.applicationContext = applicationContext; - this.vaultProperties = vaultProperties; - this.configuration = new VaultConfiguration(vaultProperties); - - VaultEndpointProvider provider = endpointProvider.getIfAvailable(); - - if (provider == null) { - provider = SimpleVaultEndpointProvider.of(this.configuration.createVaultEndpoint()); - } - - this.endpointProvider = provider; - this.customizers = new ArrayList<>(customizers.getIfAvailable(Collections::emptyList)); - AnnotationAwareOrderComparator.sort(this.customizers); - - this.requestCustomizers = new ArrayList<>(requestCustomizers.getIfAvailable(Collections::emptyList)); - AnnotationAwareOrderComparator.sort(this.requestCustomizers); - } - - /** - * Create a {@link RestTemplateBuilder} initialized with {@link VaultEndpointProvider} - * and {@link ClientHttpRequestFactory}. May be overridden by subclasses. - * @param requestFactory the {@link ClientHttpRequestFactory}. - * @return the {@link RestTemplateBuilder}. - * @since 2.3 - * @see #clientHttpRequestFactoryWrapper() - */ - protected RestTemplateBuilder restTemplateBuilder(ClientHttpRequestFactory requestFactory) { - - return this.configuration.createRestTemplateBuilder(requestFactory, this.endpointProvider, this.customizers, - this.requestCustomizers); - } - - /** - * Creates a {@link ClientFactoryWrapper} containing a - * {@link ClientHttpRequestFactory}. {@link ClientHttpRequestFactory} is not exposed - * as root bean because {@link ClientHttpRequestFactory} is configured with - * {@link ClientOptions} and {@link SslConfiguration} which are not necessarily - * applicable for the whole application. - * @return the {@link ClientFactoryWrapper} to wrap a {@link ClientHttpRequestFactory} - * instance. - */ - @Bean - @ConditionalOnMissingBean - public ClientFactoryWrapper clientHttpRequestFactoryWrapper() { - return new ClientFactoryWrapper(this.configuration.createClientHttpRequestFactory()); - } - - /** - * Create a {@link RestTemplateFactory} bean that is used to produce - * {@link RestTemplate}. - * @param clientFactoryWrapper the {@link ClientFactoryWrapper}. - * @return the {@link RestTemplateFactory}. - * @since 3.0 - * @see #clientHttpRequestFactoryWrapper() - */ - @Bean - @ConditionalOnMissingBean - public RestTemplateFactory vaultRestTemplateFactory(ClientFactoryWrapper clientFactoryWrapper) { - return new DefaultRestTemplateFactory(clientFactoryWrapper.getClientHttpRequestFactory(), - this::restTemplateBuilder); - } - - /** - * Creates a {@link VaultTemplate}. - * @param clientFactoryWrapper the {@link ClientFactoryWrapper}. - * @return the {@link VaultTemplate} bean. - * @see VaultAutoConfiguration#clientHttpRequestFactoryWrapper() - */ - @Bean - @ConditionalOnMissingBean(VaultOperations.class) - public VaultTemplate vaultTemplate(ClientFactoryWrapper clientFactoryWrapper) { - - VaultProperties.AuthenticationMethod authentication = this.vaultProperties.getAuthentication(); - RestTemplateBuilder restTemplateBuilder = restTemplateBuilder( - clientFactoryWrapper.getClientHttpRequestFactory()); - - if (authentication == VaultProperties.AuthenticationMethod.NONE) { - return new VaultTemplate(restTemplateBuilder); - } - - return new VaultTemplate(restTemplateBuilder, this.applicationContext.getBean(SessionManager.class)); - } - - /** - * Creates a new {@link TaskSchedulerWrapper} that encapsulates a bean implementing - * {@link TaskScheduler} and {@link AsyncTaskExecutor}. - * @return the {@link TaskSchedulerWrapper} bean. - * @see ThreadPoolTaskScheduler - */ - @Bean - @Lazy - @ConditionalOnMissingBean(TaskSchedulerWrapper.class) - public TaskSchedulerWrapper vaultTaskScheduler() { - - ThreadPoolTaskScheduler threadPoolTaskScheduler = VaultConfiguration.createScheduler(); - - // This is to destroy bootstrap resources - // otherwise, the bootstrap context is not shut down cleanly - this.applicationContext.registerShutdownHook(); - - return new TaskSchedulerWrapper(threadPoolTaskScheduler); - } - - /** - * @param clientAuthentication the {@link ClientAuthentication}. - * @param asyncTaskExecutorFactory the {@link ObjectFactory} for - * {@link TaskSchedulerWrapper}. - * @param restTemplateFactory the {@link RestTemplateFactory}. - * @return the {@link SessionManager} for Vault session management. - * @see SessionManager - * @see LifecycleAwareSessionManager - */ - @Bean - @ConditionalOnMissingBean - @ConditionalOnAuthentication - public SessionManager vaultSessionManager(ClientAuthentication clientAuthentication, - ObjectFactory asyncTaskExecutorFactory, RestTemplateFactory restTemplateFactory) { - - return this.configuration.createSessionManager(clientAuthentication, - () -> asyncTaskExecutorFactory.getObject().getTaskScheduler(), restTemplateFactory); - } - - /** - * @param clientFactoryWrapper the {@link ClientFactoryWrapper}. - * @param restTemplateFactory the {@link RestTemplateFactory}. - * @return the {@link ClientAuthentication} to obtain a - * {@link org.springframework.vault.support.VaultToken}. - * @see SessionManager - * @see LifecycleAwareSessionManager - */ - @Bean - @ConditionalOnMissingBean - @ConditionalOnAuthentication - public ClientAuthentication clientAuthentication(ClientFactoryWrapper clientFactoryWrapper, - RestTemplateFactory restTemplateFactory) { - - RestTemplate externalRestOperations = new RestTemplate(clientFactoryWrapper.getClientHttpRequestFactory()); - - this.customizers.forEach(customizer -> customizer.customize(externalRestOperations)); - - RestTemplate restTemplate = restTemplateFactory.create(); - ClientAuthenticationFactory factory = new ClientAuthenticationFactory(this.vaultProperties, restTemplate, - externalRestOperations); - - return factory.createClientAuthentication(); - } - - /** - * Wrapper to keep {@link TaskScheduler} local to Spring Cloud Vault. - */ - public static class TaskSchedulerWrapper implements InitializingBean, DisposableBean { - - private final ThreadPoolTaskScheduler taskScheduler; - - private final boolean acceptAfterPropertiesSet; - - public TaskSchedulerWrapper(ThreadPoolTaskScheduler taskScheduler) { - this(taskScheduler, true); - } - - public TaskSchedulerWrapper(ThreadPoolTaskScheduler taskScheduler, boolean acceptAfterPropertiesSet) { - this.taskScheduler = taskScheduler; - this.acceptAfterPropertiesSet = acceptAfterPropertiesSet; - } - - public ThreadPoolTaskScheduler getTaskScheduler() { - return this.taskScheduler; - } - - @Override - public void destroy() { - this.taskScheduler.destroy(); - } - - @Override - public void afterPropertiesSet() { - - if (this.acceptAfterPropertiesSet) { - this.taskScheduler.afterPropertiesSet(); - } - } - - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapConfiguration.java deleted file mode 100644 index de44953b..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapConfiguration.java +++ /dev/null @@ -1,53 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.List; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.bootstrap.BootstrapConfiguration; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.vault.client.RestTemplateCustomizer; -import org.springframework.vault.client.RestTemplateRequestCustomizer; -import org.springframework.vault.client.VaultEndpointProvider; - -/** - * {@link BootstrapConfiguration Boostrap configuration} for Spring Vault support. - * - * @author Spencer Gibb - * @author Mark Paluch - * @deprecated since 3.0, use {@link VaultReactiveAutoConfiguration} through - * {@code @EnableAutoConfiguration}. - */ -@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true) -@EnableConfigurationProperties(VaultProperties.class) -@Order(Ordered.LOWEST_PRECEDENCE - 5) -@Deprecated -public class VaultBootstrapConfiguration extends VaultAutoConfiguration { - - public VaultBootstrapConfiguration(ConfigurableApplicationContext applicationContext, - VaultProperties vaultProperties, ObjectProvider endpointProvider, - ObjectProvider> customizers, - ObjectProvider>> requestCustomizers) { - super(applicationContext, vaultProperties, endpointProvider, customizers, requestCustomizers); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapPropertySourceConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapPropertySourceConfiguration.java deleted file mode 100644 index 0c4a9cad..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapPropertySourceConfiguration.java +++ /dev/null @@ -1,146 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.bootstrap.config.PropertySourceLocator; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Lazy; -import org.springframework.core.Ordered; -import org.springframework.core.annotation.Order; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.vault.authentication.LifecycleAwareSessionManager; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.core.lease.SecretLeaseContainer; - -import static org.springframework.cloud.vault.config.VaultAutoConfiguration.TaskSchedulerWrapper; - -/** - * {@link org.springframework.cloud.bootstrap.BootstrapConfiguration Auto-configuration} - * for Spring Vault's {@link PropertySourceLocator} support. - * - * @author Mark Paluch - * @author Grenville Wilson - * @author Mårten Svantesson - * @since 1.1 - * @deprecated since 3.0, use {@code spring.config.import=vault://} instead. - */ -@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true) -@EnableConfigurationProperties(VaultKeyValueBackendProperties.class) -@Order(Ordered.LOWEST_PRECEDENCE - 10) -@Deprecated -public class VaultBootstrapPropertySourceConfiguration implements InitializingBean { - - private final VaultConfiguration configuration; - - private final ConfigurableApplicationContext applicationContext; - - @Nullable - private Collection vaultSecretBackendDescriptors; - - @Nullable - private Collection vaultSecretBackendDescriptorFactories; - - @Nullable - private Collection> factories; - - public VaultBootstrapPropertySourceConfiguration(VaultProperties vaultProperties, - ConfigurableApplicationContext applicationContext) { - this.configuration = new VaultConfiguration(vaultProperties); - this.applicationContext = applicationContext; - } - - @Override - @SuppressWarnings("unchecked") - public void afterPropertiesSet() { - - this.vaultSecretBackendDescriptors = this.applicationContext.getBeansOfType(VaultSecretBackendDescriptor.class) - .values(); - - this.vaultSecretBackendDescriptorFactories = this.applicationContext - .getBeansOfType(VaultSecretBackendDescriptorFactory.class).values(); - - this.factories = (Collection) this.applicationContext.getBeansOfType(SecretBackendMetadataFactory.class) - .values(); - } - - @Bean - public PropertySourceLocator vaultPropertySourceLocator(VaultOperations operations, VaultProperties vaultProperties, - VaultKeyValueBackendProperties kvBackendProperties, - ObjectFactory secretLeaseContainerObjectFactory) { - - Assert.state(this.vaultSecretBackendDescriptors != null, "VaultSecretBackendDescriptors must not be null"); - Assert.state(this.factories != null, "SecretBackendMetadataFactories must not be null"); - - VaultConfigTemplate vaultConfigTemplate = new VaultConfigTemplate(operations, vaultProperties); - - Collection vaultConfigurers = this.applicationContext.getBeansOfType(VaultConfigurer.class) - .values(); - - List descriptors = new ArrayList<>(this.vaultSecretBackendDescriptors); - this.vaultSecretBackendDescriptorFactories.forEach(it -> descriptors.addAll(it.create())); - - PropertySourceLocatorConfigurationFactory factory = new PropertySourceLocatorConfigurationFactory( - vaultConfigurers, descriptors, this.factories); - - PropertySourceLocatorConfiguration configuration = factory.getPropertySourceConfiguration(kvBackendProperties); - - VaultProperties.ConfigLifecycle lifecycle = vaultProperties.getConfig().getLifecycle(); - - if (lifecycle.isEnabled()) { - - // This is to destroy bootstrap resources - // otherwise, the bootstrap context is not shut down cleanly - this.applicationContext.registerShutdownHook(); - - SecretLeaseContainer secretLeaseContainer = secretLeaseContainerObjectFactory.getObject(); - - secretLeaseContainer.start(); - - return new LeasingVaultPropertySourceLocator(vaultProperties, configuration, secretLeaseContainer); - } - - return new VaultPropertySourceLocator(vaultConfigTemplate, vaultProperties, configuration); - } - - /** - * @param vaultOperations the {@link VaultOperations}. - * @param taskSchedulerWrapper the {@link TaskSchedulerWrapper}. - * @return the {@link SessionManager} for Vault session management. - * @see SessionManager - * @see LifecycleAwareSessionManager - */ - @Bean - @Lazy - @ConditionalOnMissingBean - public SecretLeaseContainer secretLeaseContainer(VaultOperations vaultOperations, - TaskSchedulerWrapper taskSchedulerWrapper) { - return this.configuration.createSecretLeaseContainer(vaultOperations, taskSchedulerWrapper::getTaskScheduler); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapper.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapper.java deleted file mode 100644 index 18d75598..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultBootstrapper.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.boot.BootstrapRegistryInitializer; -import org.springframework.util.Assert; - -/** - * Utility to customize Bootstrapping of Vault when using the ConfigData API when - * importing {@code vault://}. - * - * @author Mark Paluch - * @since 3.0 - */ -public abstract class VaultBootstrapper { - - private VaultBootstrapper() { - } - - /** - * Create a {@link BootstrapRegistryInitializer} that configures a - * {@link VaultConfigurer}. - * @param configurer the configurer to apply. - * @return the bootstrapper object. - */ - public static BootstrapRegistryInitializer fromConfigurer(VaultConfigurer configurer) { - - Assert.notNull(configurer, "VaultConfigurer must not be null"); - - return registry -> registry.register(VaultConfigurer.class, context -> configurer); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigDataLoader.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigDataLoader.java deleted file mode 100644 index 70a88b7e..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigDataLoader.java +++ /dev/null @@ -1,606 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.lang.reflect.Field; -import java.lang.reflect.Modifier; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.concurrent.atomic.AtomicReference; -import java.util.function.Consumer; -import java.util.function.Function; -import java.util.function.Supplier; - -import org.apache.commons.logging.Log; -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; -import org.springframework.boot.BootstrapContext; -import org.springframework.boot.BootstrapRegistry; -import org.springframework.boot.BootstrapRegistryInitializer; -import org.springframework.boot.ConfigurableBootstrapContext; -import org.springframework.boot.context.config.ConfigData; -import org.springframework.boot.context.config.ConfigDataLoader; -import org.springframework.boot.context.config.ConfigDataLoaderContext; -import org.springframework.boot.context.config.ConfigDataLocationNotFoundException; -import org.springframework.boot.logging.DeferredLogFactory; -import org.springframework.cloud.vault.config.VaultAutoConfiguration.TaskSchedulerWrapper; -import org.springframework.cloud.vault.config.VaultReactiveAutoConfiguration.ClientHttpConnectorWrapper; -import org.springframework.context.ApplicationEventPublisherAware; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.support.GenericApplicationContext; -import org.springframework.core.env.PropertySource; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.lang.Nullable; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import org.springframework.util.ClassUtils; -import org.springframework.util.ReflectionUtils; -import org.springframework.vault.VaultException; -import org.springframework.vault.authentication.AuthenticationStepsFactory; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.ReactiveSessionManager; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.authentication.VaultTokenSupplier; -import org.springframework.vault.client.ClientHttpRequestFactoryFactory; -import org.springframework.vault.client.RestTemplateBuilder; -import org.springframework.vault.client.RestTemplateFactory; -import org.springframework.vault.client.SimpleVaultEndpointProvider; -import org.springframework.vault.client.VaultEndpointProvider; -import org.springframework.vault.client.WebClientBuilder; -import org.springframework.vault.client.WebClientFactory; -import org.springframework.vault.config.AbstractVaultConfiguration.ClientFactoryWrapper; -import org.springframework.vault.core.ReactiveVaultTemplate; -import org.springframework.vault.core.VaultTemplate; -import org.springframework.vault.core.env.LeaseAwareVaultPropertySource; -import org.springframework.vault.core.lease.SecretLeaseContainer; -import org.springframework.vault.core.lease.domain.RequestedSecret; -import org.springframework.vault.core.lease.event.LeaseErrorListener; -import org.springframework.web.client.RestTemplate; - -/** - * {@link ConfigDataLoader} for Vault for {@link VaultConfigLocation}. This class - * materializes {@link PropertySource property sources} by using Vault and - * {@link VaultConfigLocation}. This class also ensures that all necessary infrastructure - * beans are registered in the {@link BootstrapRegistry}. Registrations made by this - * config data loader are typically propagated into the {@link BeanFactory} as this - * configuration mirrors to some extent {@link VaultAutoConfiguration} and - * {@link VaultReactiveAutoConfiguration}. - *

- * Infrastructure beans can be customized by registering instances through - * {@link BootstrapRegistryInitializer}. - * - * @author Mark Paluch - * @since 3.0 - * @see VaultConfigLocation - * @see VaultAutoConfiguration - * @see VaultReactiveAutoConfiguration - */ -public class VaultConfigDataLoader implements ConfigDataLoader { - - private final static ConfigData SKIP_LOCATION = null; - - final static boolean reactorPresent = ClassUtils.isPresent("reactor.core.publisher.Flux", - VaultConfigDataLoader.class.getClassLoader()); - - final static boolean webclientPresent = ClassUtils.isPresent( - "org.springframework.web.reactive.function.client.WebClient", VaultConfigDataLoader.class.getClassLoader()); - - private final static boolean REGISTER_REACTIVE_INFRASTRUCTURE = reactorPresent && webclientPresent; - - private final DeferredLogFactory logFactory; - - public VaultConfigDataLoader(DeferredLogFactory logFactory) { - this.logFactory = logFactory; - reconfigureLoggers(logFactory); - } - - @Override - public ConfigData load(ConfigDataLoaderContext context, VaultConfigLocation location) - throws ConfigDataLocationNotFoundException { - - ConfigurableBootstrapContext bootstrap = context.getBootstrapContext(); - VaultProperties vaultProperties = bootstrap.get(VaultProperties.class); - - if (!vaultProperties.isEnabled()) { - return SKIP_LOCATION; - } - - if (vaultProperties.getSession().getLifecycle().isEnabled() - || vaultProperties.getConfig().getLifecycle().isEnabled()) { - registerVaultTaskScheduler(bootstrap); - } - - registerImperativeInfrastructure(bootstrap, vaultProperties); - - if (REGISTER_REACTIVE_INFRASTRUCTURE && vaultProperties.getReactive().isEnabled()) { - registerReactiveInfrastructure(bootstrap, vaultProperties); - } - - registerVaultConfigTemplate(bootstrap, vaultProperties); - - if (vaultProperties.getConfig().getLifecycle().isEnabled()) { - registerSecretLeaseContainer(bootstrap, new VaultConfiguration(vaultProperties)); - } - - return loadConfigData(location, bootstrap, vaultProperties); - } - - private ConfigData loadConfigData(VaultConfigLocation location, ConfigurableBootstrapContext bootstrap, - VaultProperties vaultProperties) { - - if (location.getSecretBackendMetadata() instanceof ApplicationEventPublisherAware) { - - bootstrap.addCloseListener(event -> { - ((ApplicationEventPublisherAware) location.getSecretBackendMetadata()) - .setApplicationEventPublisher(event.getApplicationContext()); - }); - } - - if (vaultProperties.getConfig().getLifecycle().isEnabled()) { - - RequestedSecret secret = getRequestedSecret(location.getSecretBackendMetadata()); - - if (vaultProperties.isFailFast()) { - return new ConfigData(Collections.singleton(createLeasingPropertySourceFailFast( - bootstrap.get(SecretLeaseContainer.class), secret, location.getSecretBackendMetadata()))); - } - - return createConfigData(() -> createLeasingPropertySource(bootstrap.get(SecretLeaseContainer.class), secret, - location.getSecretBackendMetadata())); - } - - return createConfigData(() -> { - VaultConfigTemplate configTemplate = bootstrap.get(VaultConfigTemplate.class); - - return createVaultPropertySource(configTemplate, vaultProperties.isFailFast(), - location.getSecretBackendMetadata()); - }); - } - - private void registerImperativeInfrastructure(ConfigurableBootstrapContext bootstrap, - VaultProperties vaultProperties) { - - ImperativeInfrastructure infra = new ImperativeInfrastructure(bootstrap, vaultProperties, this.logFactory); - - infra.registerClientHttpRequestFactoryWrapper(); - infra.registerRestTemplateBuilder(); - infra.registerVaultRestTemplateFactory(); - - VaultProperties.AuthenticationMethod authentication = vaultProperties.getAuthentication(); - - if (authentication == VaultProperties.AuthenticationMethod.NONE) { - registerIfAbsent(bootstrap, "vaultTemplate", VaultTemplate.class, - ctx -> new VaultTemplate(ctx.get(RestTemplateBuilder.class))); - } - else { - - infra.registerClientAuthentication(); - - if (!REGISTER_REACTIVE_INFRASTRUCTURE || !vaultProperties.getReactive().isEnabled()) { - infra.registerVaultSessionManager(); - } - - registerIfAbsent(bootstrap, "vaultTemplate", VaultTemplate.class, - ctx -> new VaultTemplate(bootstrap.get(RestTemplateBuilder.class), - bootstrap.get(SessionManager.class))); - } - } - - private void registerReactiveInfrastructure(ConfigurableBootstrapContext bootstrap, - VaultProperties vaultProperties) { - - ReactiveInfrastructure reactiveInfrastructure = new ReactiveInfrastructure(bootstrap, vaultProperties, - this.logFactory); - reactiveInfrastructure.registerClientHttpConnectorWrapper(); - reactiveInfrastructure.registerWebClientBuilder(); - reactiveInfrastructure.registerWebClientFactory(); - - VaultProperties.AuthenticationMethod authentication = vaultProperties.getAuthentication(); - - if (authentication == VaultProperties.AuthenticationMethod.NONE) { - registerIfAbsent(bootstrap, "reactiveVaultTemplate", ReactiveVaultTemplate.class, - ctx -> new ReactiveVaultTemplate(ctx.get(WebClientBuilder.class))); - } - else { - - reactiveInfrastructure.registerTokenSupplier(); - reactiveInfrastructure.registerReactiveSessionManager(); - reactiveInfrastructure.registerSessionManager(); - - registerIfAbsent(bootstrap, "reactiveVaultTemplate", ReactiveVaultTemplate.class, - ctx -> new ReactiveVaultTemplate(bootstrap.get(WebClientBuilder.class), - bootstrap.get(ReactiveSessionManager.class))); - } - } - - static ConfigData createConfigData(Supplier> propertySourceSupplier) { - return new ConfigData(Collections.singleton(propertySourceSupplier.get())); - } - - private void registerVaultConfigTemplate(ConfigurableBootstrapContext bootstrap, VaultProperties vaultProperties) { - bootstrap.registerIfAbsent(VaultConfigTemplate.class, - ctx -> new VaultConfigTemplate(ctx.get(VaultTemplate.class), vaultProperties)); - } - - private void registerVaultTaskScheduler(ConfigurableBootstrapContext bootstrap) { - registerIfAbsent(bootstrap, "vaultTaskScheduler", TaskSchedulerWrapper.class, () -> { - - ThreadPoolTaskScheduler scheduler = VaultConfiguration.createScheduler(); - - scheduler.afterPropertiesSet(); - - // avoid double-initialization - return new TaskSchedulerWrapper(scheduler, false); - }, ConfigurableApplicationContext::registerShutdownHook); - } - - private void registerSecretLeaseContainer(ConfigurableBootstrapContext bootstrap, - VaultConfiguration vaultConfiguration) { - registerIfAbsent(bootstrap, "secretLeaseContainer", SecretLeaseContainer.class, ctx -> { - - SecretLeaseContainer container = vaultConfiguration.createSecretLeaseContainer(ctx.get(VaultTemplate.class), - () -> ctx.get(TaskSchedulerWrapper.class).getTaskScheduler()); - - try { - container.afterPropertiesSet(); - } - catch (Exception e) { - ReflectionUtils.rethrowRuntimeException(e); - } - container.start(); - - return container; - }, ConfigurableApplicationContext::registerShutdownHook); - } - - private PropertySource createVaultPropertySource(VaultConfigOperations configOperations, boolean failFast, - SecretBackendMetadata accessor) { - - VaultPropertySource vaultPropertySource = new VaultPropertySource(configOperations, failFast, accessor); - vaultPropertySource.init(); - return vaultPropertySource; - } - - private PropertySource createLeasingPropertySource(SecretLeaseContainer secretLeaseContainer, - RequestedSecret secret, SecretBackendMetadata accessor) { - - if (accessor instanceof LeasingSecretBackendMetadata) { - ((LeasingSecretBackendMetadata) accessor).beforeRegistration(secret, secretLeaseContainer); - } - - LeaseAwareVaultPropertySource propertySource = new LeaseAwareVaultPropertySource(accessor.getName(), - secretLeaseContainer, secret, accessor.getPropertyTransformer()); - - if (accessor instanceof LeasingSecretBackendMetadata) { - ((LeasingSecretBackendMetadata) accessor).afterRegistration(secret, secretLeaseContainer); - } - - return propertySource; - } - - private PropertySource createLeasingPropertySourceFailFast(SecretLeaseContainer secretLeaseContainer, - RequestedSecret secret, SecretBackendMetadata accessor) { - - final AtomicReference errorRef = new AtomicReference<>(); - - LeaseErrorListener errorListener = (leaseEvent, exception) -> { - - if (leaseEvent.getSource() == secret) { - errorRef.compareAndSet(null, exception); - } - }; - - secretLeaseContainer.addErrorListener(errorListener); - try { - return createLeasingPropertySource(secretLeaseContainer, secret, accessor); - } - finally { - secretLeaseContainer.removeLeaseErrorListener(errorListener); - - Exception exception = errorRef.get(); - if (exception != null) { - if (exception instanceof VaultException) { - throw (VaultException) exception; - } - throw new VaultException( - String.format("Cannot initialize PropertySource for secret at %s", secret.getPath()), - exception); - } - } - } - - private RequestedSecret getRequestedSecret(SecretBackendMetadata accessor) { - - if (accessor instanceof LeasingSecretBackendMetadata) { - - LeasingSecretBackendMetadata leasingBackend = (LeasingSecretBackendMetadata) accessor; - return RequestedSecret.from(leasingBackend.getLeaseMode(), accessor.getPath()); - } - - if (accessor instanceof KeyValueSecretBackendMetadata) { - return RequestedSecret.rotating(accessor.getPath()); - } - - return RequestedSecret.renewable(accessor.getPath()); - } - - static void registerIfAbsent(ConfigurableBootstrapContext bootstrap, String beanName, Class instanceType, - Supplier instanceSupplier) { - registerIfAbsent(bootstrap, beanName, instanceType, ctx -> instanceSupplier.get(), ctx -> { - }); - } - - static void registerIfAbsent(ConfigurableBootstrapContext bootstrap, String beanName, Class instanceType, - Supplier instanceSupplier, Consumer contextCustomizer) { - registerIfAbsent(bootstrap, beanName, instanceType, ctx -> instanceSupplier.get(), contextCustomizer); - } - - static void registerIfAbsent(ConfigurableBootstrapContext bootstrap, String beanName, Class instanceType, - Function instanceSupplier) { - registerIfAbsent(bootstrap, beanName, instanceType, instanceSupplier, ctx -> { - }); - } - - static void registerIfAbsent(ConfigurableBootstrapContext bootstrap, String beanName, Class instanceType, - Function instanceSupplier, - Consumer contextCustomizer) { - - bootstrap.registerIfAbsent(instanceType, instanceSupplier::apply); - - bootstrap.addCloseListener(event -> { - - GenericApplicationContext gac = (GenericApplicationContext) event.getApplicationContext(); - - ConfigurableListableBeanFactory factory = gac.getBeanFactory(); - - if (factory.containsSingleton(beanName) || factory.containsBeanDefinition(beanName)) { - return; - } - - contextCustomizer.accept(gac); - T instance = event.getBootstrapContext().get(instanceType); - - factory.registerSingleton(beanName, instance); - }); - } - - static void reconfigureLoggers(DeferredLogFactory logFactory) { - - List> loggers = Arrays.asList(ClientHttpRequestFactoryFactory.class, VaultPropertySource.class, - LeaseAwareVaultPropertySource.class, - forName("org.springframework.vault.core.lease.SecretLeaseContainer$LeaseRenewalScheduler"), - forName("org.springframework.vault.core.lease.SecretLeaseEventPublisher$LoggingErrorListener")); - - loggers.forEach(it -> reconfigureLogger(it, logFactory)); - } - - static void reconfigureLogger(Class type, DeferredLogFactory logFactory) { - - ReflectionUtils.doWithFields(type, field -> { - - field.setAccessible(true); - field.set(null, logFactory.getLog(type)); - }, VaultConfigDataLoader::isUpdateableLogField); - } - - static void reconfigureLogger(Object object, DeferredLogFactory logFactory) { - - ReflectionUtils.doWithFields(object.getClass(), field -> { - - field.setAccessible(true); - field.set(object, logFactory.getLog(object.getClass())); - }, VaultConfigDataLoader::isUpdateableLogField); - } - - static boolean isUpdateableLogField(Field field) { - return !Modifier.isFinal(field.getModifiers()) && field.getType().isAssignableFrom(Log.class); - } - - @Nullable - static Class forName(String name) { - try { - return ClassUtils.forName(name, VaultConfigDataLocationResolver.class.getClassLoader()); - } - catch (ClassNotFoundException e) { - return null; - } - } - - /** - * Support class to register imperative infrastructure bootstrap instances and beans. - *

- * Mirrors {@link VaultAutoConfiguration}. - */ - static class ImperativeInfrastructure { - - private final ConfigurableBootstrapContext bootstrap; - - private final VaultProperties vaultProperties; - - private final VaultConfiguration configuration; - - private final VaultEndpointProvider endpointProvider; - - private final DeferredLogFactory logFactory; - - ImperativeInfrastructure(ConfigurableBootstrapContext bootstrap, VaultProperties vaultProperties, - DeferredLogFactory logFactory) { - this.bootstrap = bootstrap; - this.vaultProperties = vaultProperties; - this.configuration = new VaultConfiguration(vaultProperties); - this.endpointProvider = SimpleVaultEndpointProvider.of(this.configuration.createVaultEndpoint()); - this.logFactory = logFactory; - } - - void registerClientHttpRequestFactoryWrapper() { - registerIfAbsent(this.bootstrap, "clientHttpRequestFactoryWrapper", ClientFactoryWrapper.class, () -> { - - ClientHttpRequestFactory factory = this.configuration.createClientHttpRequestFactory(); - - // early initialization - try { - new ClientFactoryWrapper(factory).afterPropertiesSet(); - } - catch (Exception e) { - ReflectionUtils.rethrowRuntimeException(e); - } - - return new NonInitializingClientFactoryWrapper(factory); - }); - } - - void registerRestTemplateBuilder() { - // not a bean - this.bootstrap.registerIfAbsent(RestTemplateBuilder.class, - ctx -> this.configuration.createRestTemplateBuilder( - ctx.get(ClientFactoryWrapper.class).getClientHttpRequestFactory(), this.endpointProvider, - Collections.emptyList(), Collections.emptyList())); - } - - void registerVaultRestTemplateFactory() { - registerIfAbsent(this.bootstrap, "vaultRestTemplateFactory", RestTemplateFactory.class, - ctx -> new DefaultRestTemplateFactory( - ctx.get(ClientFactoryWrapper.class).getClientHttpRequestFactory(), - requestFactory -> this.configuration.createRestTemplateBuilder(requestFactory, - this.endpointProvider, Collections.emptyList(), Collections.emptyList()))); - } - - void registerClientAuthentication() { - registerIfAbsent(this.bootstrap, "clientAuthentication", ClientAuthentication.class, ctx -> { - - ClientHttpRequestFactory factory = this.bootstrap.get(ClientFactoryWrapper.class) - .getClientHttpRequestFactory(); - - RestTemplate externalRestTemplate = new RestTemplate(factory); - - ClientAuthenticationFactory authenticationFactory = new ClientAuthenticationFactory( - this.vaultProperties, this.bootstrap.get(RestTemplateFactory.class).create(), - externalRestTemplate); - return authenticationFactory.createClientAuthentication(); - }); - } - - void registerVaultSessionManager() { - registerIfAbsent(this.bootstrap, "vaultSessionManager", SessionManager.class, ctx -> { - SessionManager sessionManager = this.configuration.createSessionManager( - ctx.get(ClientAuthentication.class), - () -> ctx.get(TaskSchedulerWrapper.class).getTaskScheduler(), - ctx.get(RestTemplateFactory.class)); - reconfigureLogger(sessionManager, this.logFactory); - return sessionManager; - }); - } - - } - - /** - * Support class to register reactive infrastructure bootstrap instances and beans. - * Mirrors {@link VaultReactiveAutoConfiguration}. - */ - static class ReactiveInfrastructure { - - private final ConfigurableBootstrapContext bootstrap; - - private final VaultReactiveConfiguration configuration; - - private final VaultEndpointProvider endpointProvider; - - private final DeferredLogFactory logFactory; - - ReactiveInfrastructure(ConfigurableBootstrapContext bootstrap, VaultProperties vaultProperties, - DeferredLogFactory logFactory) { - this.bootstrap = bootstrap; - this.configuration = new VaultReactiveConfiguration(vaultProperties); - this.endpointProvider = SimpleVaultEndpointProvider - .of(new VaultConfiguration(vaultProperties).createVaultEndpoint()); - this.logFactory = logFactory; - } - - void registerClientHttpConnectorWrapper() { - registerIfAbsent(this.bootstrap, "clientHttpConnectorWrapper", ClientHttpConnectorWrapper.class, - () -> new ClientHttpConnectorWrapper(this.configuration.createClientHttpConnector())); - } - - public void registerWebClientBuilder() { - // not a bean - this.bootstrap.registerIfAbsent(WebClientBuilder.class, - ctx -> this.configuration.createWebClientBuilder( - ctx.get(ClientHttpConnectorWrapper.class).getConnector(), this.endpointProvider, - Collections.emptyList())); - } - - void registerWebClientFactory() { - registerIfAbsent(this.bootstrap, "vaultWebClientFactory", WebClientFactory.class, - ctx -> new DefaultWebClientFactory(ctx.get(ClientHttpConnectorWrapper.class).getConnector(), - connector -> this.configuration.createWebClientBuilder(connector, this.endpointProvider, - Collections.emptyList()))); - } - - void registerTokenSupplier() { - - registerIfAbsent(this.bootstrap, "vaultTokenSupplier", VaultTokenSupplier.class, - ctx -> this.configuration.createVaultTokenSupplier(ctx.get(WebClientFactory.class), () -> { - if (this.bootstrap.isRegistered(AuthenticationStepsFactory.class)) { - return this.bootstrap.get(AuthenticationStepsFactory.class); - } - - return null; - }, () -> { - if (this.bootstrap.isRegistered(ClientAuthentication.class)) { - return this.bootstrap.get(ClientAuthentication.class); - } - - return null; - })); - } - - void registerReactiveSessionManager() { - - registerIfAbsent(this.bootstrap, "reactiveVaultSessionManager", ReactiveSessionManager.class, - ctx -> this.configuration.createReactiveSessionManager(ctx.get(VaultTokenSupplier.class), - () -> ctx.get(TaskSchedulerWrapper.class).getTaskScheduler(), - ctx.get(WebClientFactory.class))); - } - - void registerSessionManager() { - registerIfAbsent(this.bootstrap, "vaultSessionManager", SessionManager.class, ctx -> { - SessionManager sessionManager = this.configuration - .createSessionManager(ctx.get(ReactiveSessionManager.class)); - reconfigureLogger(sessionManager, this.logFactory); - return sessionManager; - }); - } - - } - - /** - * Wrapper for {@link ClientHttpRequestFactory} that suppresses - * {@link #afterPropertiesSet()} to avoid double-initialization. - */ - private static class NonInitializingClientFactoryWrapper extends ClientFactoryWrapper { - - NonInitializingClientFactoryWrapper(ClientHttpRequestFactory clientHttpRequestFactory) { - super(clientHttpRequestFactory); - } - - @Override - public void afterPropertiesSet() { - } - - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolver.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolver.java deleted file mode 100644 index c24d5894..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolver.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; - -import org.springframework.boot.BootstrapRegistry; -import org.springframework.boot.ConfigurableBootstrapContext; -import org.springframework.boot.context.config.ConfigDataLocation; -import org.springframework.boot.context.config.ConfigDataLocationNotFoundException; -import org.springframework.boot.context.config.ConfigDataLocationResolver; -import org.springframework.boot.context.config.ConfigDataLocationResolverContext; -import org.springframework.boot.context.config.ConfigDataResourceNotFoundException; -import org.springframework.boot.context.config.Profiles; -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.bind.Bindable; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.annotation.MergedAnnotations; -import org.springframework.core.io.support.SpringFactoriesLoader; -import org.springframework.util.ClassUtils; -import org.springframework.util.StringUtils; -import org.springframework.vault.core.util.PropertyTransformer; -import org.springframework.vault.core.util.PropertyTransformers; -import org.springframework.web.util.UriComponents; -import org.springframework.web.util.UriComponentsBuilder; - -/** - * {@link ConfigDataLocationResolver} for Vault resolving {@link VaultConfigLocation} - * using the {@code vault:} prefix. - *

- * Resolution considers contextual locations as we as default locations. Contextual - * locations such as {@code vault:secret/my-application} are considered to be context - * paths for the Key-Value secrets backend. Using a default location {@code vault:} - * imports all enabled {@link VaultSecretBackendDescriptor secret backends } by creating - * {@link SecretBackendMetadata} from {@link SecretBackendMetadataFactory}. Note that both - * types,{@link VaultSecretBackendDescriptor} and {@link SecretBackendMetadataFactory} are - * resolved through {@link SpringFactoriesLoader spring.factories} to allow optional - * presence/absence on the class path. - *

- * Mixing paths - * ({@code spring.config.import=vault:,vault:secret/my-application,vault:secret/other-location}) - * is possible as each config location creates an individual {@link VaultConfigLocation}. - * By enabling/disabling {@link VaultSecretBackendDescriptor#isEnabled() a - * VaultSecretBackendDescriptor}, you can control the amount of secret backends that are - * imported through the default location. - *

- * You can customize the default location capabilities by registering - * {@link VaultConfigurer} in the {@link BootstrapRegistry}. For example: - * - *

- * VaultConfigurer configurer = …;
- * SpringApplication application = …;
- *
- * application.addBootstrapper(registy -> register(VaultConfigurer.class, context -> configurer));
- * 
- *

- * Registers also {@link VaultProperties} in the {@link BootstrapRegistry} that is - * required later on by {@link VaultConfigDataLoader}. - * - * @author Mark Paluch - * @author Jeffrey van der Laan - * @since 3.0 - * @see VaultConfigurer - * @see BootstrapRegistry - * @see VaultConfigDataLoader - */ -public class VaultConfigDataLocationResolver implements ConfigDataLocationResolver { - - @Override - public boolean isResolvable(ConfigDataLocationResolverContext context, ConfigDataLocation location) { - return location.getValue().startsWith(VaultConfigLocation.VAULT_PREFIX); - } - - @Override - public List resolve(ConfigDataLocationResolverContext context, ConfigDataLocation location) - throws ConfigDataLocationNotFoundException, ConfigDataResourceNotFoundException { - return Collections.emptyList(); - } - - @Override - public List resolveProfileSpecific(ConfigDataLocationResolverContext context, - ConfigDataLocation location, Profiles profiles) throws ConfigDataLocationNotFoundException { - - if (!location.getValue().startsWith(VaultConfigLocation.VAULT_PREFIX)) { - return Collections.emptyList(); - } - - registerVaultProperties(context); - - if (location.getValue().equals(VaultConfigLocation.VAULT_PREFIX) - || location.getValue().equals(VaultConfigLocation.VAULT_PREFIX + "//")) { - List sorted = getSecretBackends(context, profiles); - return sorted.stream().map(it -> new VaultConfigLocation(it, location.isOptional())) - .collect(Collectors.toList()); - } - - String contextPath = location.getValue().substring(VaultConfigLocation.VAULT_PREFIX.length()); - - while (contextPath.startsWith("/")) { - contextPath = contextPath.substring(1); - } - - return Collections.singletonList( - new VaultConfigLocation(contextPath, getPropertyTransformer(contextPath), location.isOptional())); - } - - private static PropertyTransformer getPropertyTransformer(String contextPath) { - - UriComponents uriComponents = UriComponentsBuilder.fromUriString(contextPath).build(); - String prefix = uriComponents.getQueryParams().getFirst("prefix"); - - if (StringUtils.hasText(prefix) && StringUtils.hasText(uriComponents.getPath())) { - return PropertyTransformers.propertyNamePrefix(prefix); - } - - return PropertyTransformers.noop(); - } - - private static void registerVaultProperties(ConfigDataLocationResolverContext context) { - - context.getBootstrapContext().registerIfAbsent(VaultProperties.class, ignore -> { - - VaultProperties vaultProperties = context.getBinder().bindOrCreate(VaultProperties.PREFIX, - VaultProperties.class); - - vaultProperties.setApplicationName(context.getBinder().bind("spring.application.name", String.class) - .orElse(vaultProperties.getApplicationName())); - - return vaultProperties; - }); - } - - private List getSecretBackends(ConfigDataLocationResolverContext context, - Profiles profiles) { - - List descriptors = findDescriptors(context.getBinder()); - List> factories = getSecretBackendMetadataFactories(); - - Collection vaultConfigurers = getVaultConfigurers(context.getBootstrapContext()); - PropertySourceLocatorConfigurationFactory factory = new PropertySourceLocatorConfigurationFactory( - vaultConfigurers, descriptors, factories); - - VaultKeyValueBackendProperties kvProperties = getKeyValueProperties(context, profiles); - - PropertySourceLocatorConfiguration configuration = factory.getPropertySourceConfiguration(kvProperties); - - Collection secretBackends = configuration.getSecretBackends(); - - List sorted = new ArrayList<>(secretBackends); - AnnotationAwareOrderComparator.sort(sorted); - Collections.reverse(sorted); - - return sorted; - } - - private static Collection getVaultConfigurers(ConfigurableBootstrapContext bootstrapContext) { - - Collection vaultConfigurers = new ArrayList<>(1); - - if (bootstrapContext.isRegistered(VaultConfigurer.class)) { - vaultConfigurers.add(bootstrapContext.get(VaultConfigurer.class)); - } - - return vaultConfigurers; - } - - private static VaultKeyValueBackendProperties getKeyValueProperties(ConfigDataLocationResolverContext context, - Profiles profiles) { - - VaultKeyValueBackendProperties kvProperties = context.getBinder() - .bindOrCreate(VaultKeyValueBackendProperties.PREFIX, VaultKeyValueBackendProperties.class); - - Binder binder = context.getBinder(); - - kvProperties.setApplicationName(binder.bind("spring.cloud.vault.kv.application-name", String.class) - .orElseGet(() -> binder.bind("spring.cloud.vault.application-name", String.class) - .orElseGet(() -> binder.bind("spring.application.name", String.class).orElse("")))); - kvProperties.setProfiles(binder.bind("spring.cloud.vault.kv.profiles", Bindable.listOf(String.class)) - .orElseGet(profiles::getActive)); - - return kvProperties; - } - - private static List findDescriptors(Binder binder) { - - List descriptorsOrFactories = new ArrayList<>(); - descriptorsOrFactories.addAll(SpringFactoriesLoader.loadFactories(VaultSecretBackendDescriptor.class, - VaultConfigDataLocationResolver.class.getClassLoader())); - descriptorsOrFactories.addAll(SpringFactoriesLoader.loadFactories(VaultSecretBackendDescriptorFactory.class, - VaultConfigDataLocationResolver.class.getClassLoader())); - - List descriptors = new ArrayList<>(descriptorsOrFactories.size()); - - for (Object descriptorOrFactory : descriptorsOrFactories) { - - Class descriptorClass = descriptorOrFactory.getClass(); - - MergedAnnotations annotations = MergedAnnotations.from(descriptorClass); - if (annotations.isPresent(ConfigurationProperties.class)) { - - String prefix = annotations.get(ConfigurationProperties.class).getString("prefix"); - Object hydratedDescriptor = binder.bindOrCreate(prefix, descriptorClass); - - if (hydratedDescriptor instanceof VaultSecretBackendDescriptorFactory) { - descriptors.addAll(((VaultSecretBackendDescriptorFactory) hydratedDescriptor).create()); - } - else if (hydratedDescriptor instanceof VaultSecretBackendDescriptor) { - descriptors.add((VaultSecretBackendDescriptor) hydratedDescriptor); - } - else { - throw new IllegalStateException(String.format( - "Descriptor %s is neither implements VaultSecretBackendDescriptorFactory nor VaultSecretBackendDescriptor", - ClassUtils.getQualifiedName(descriptorOrFactory.getClass()))); - } - } - else { - throw new IllegalStateException( - String.format("VaultSecretBackendDescriptor %s is not annotated with @ConfigurationProperties", - ClassUtils.getQualifiedName(descriptorOrFactory.getClass()))); - } - } - - return descriptors; - } - - @SuppressWarnings({ "unchecked", "rawtypes" }) - private static List> getSecretBackendMetadataFactories() { - return (List) SpringFactoriesLoader.loadFactories(SecretBackendMetadataFactory.class, - VaultConfigDataLocationResolver.class.getClassLoader()); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigLocation.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigLocation.java deleted file mode 100644 index 7a893dfd..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigLocation.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.boot.context.config.ConfigDataLocation; -import org.springframework.boot.context.config.ConfigDataResource; -import org.springframework.util.Assert; -import org.springframework.util.ObjectUtils; -import org.springframework.vault.core.util.PropertyTransformer; -import org.springframework.vault.core.util.PropertyTransformers; - -/** - * Vault-specific implementation for a {@link ConfigDataLocation}. Consists of a - * {@link SecretBackendMetadata}. - * - * @author Mark Paluch - * @since 3.0 - * @see SecretBackendMetadata - */ -public class VaultConfigLocation extends ConfigDataResource { - - /** - * Prefix used to indicate a {@link VaultConfigLocation}. - */ - public static final String VAULT_PREFIX = "vault:"; - - private final SecretBackendMetadata secretBackendMetadata; - - private final boolean optional; - - /** - * Create a new {@link VaultConfigLocation} instance. - * @param contextPath the context path - * @param optional if the resource is optional - */ - public VaultConfigLocation(String contextPath, boolean optional) { - this(contextPath, PropertyTransformers.noop(), optional); - } - - /** - * Create a new {@link VaultConfigLocation} instance. - * @param contextPath the context path - * @param propertyTransformer the property transformer - * @param optional if the resource is optional - * @since 3.0.4 - */ - public VaultConfigLocation(String contextPath, PropertyTransformer propertyTransformer, boolean optional) { - - super(optional); - - Assert.hasText(contextPath, "Location must not be empty"); - validatePath(contextPath); - - this.secretBackendMetadata = KeyValueSecretBackendMetadata.create(contextPath, propertyTransformer); - this.optional = optional; - } - - /** - * Create a new {@link VaultConfigLocation} instance. - * @param secretBackendMetadata the backend descriptor. - * @param optional if the resource is optional - */ - public VaultConfigLocation(SecretBackendMetadata secretBackendMetadata, boolean optional) { - - Assert.notNull(secretBackendMetadata, "SecretBackendMetadata must not be null"); - - validatePath(secretBackendMetadata.getPath()); - this.secretBackendMetadata = secretBackendMetadata; - this.optional = optional; - } - - public SecretBackendMetadata getSecretBackendMetadata() { - return this.secretBackendMetadata; - } - - public boolean isOptional() { - return this.optional; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof VaultConfigLocation)) { - return false; - } - VaultConfigLocation that = (VaultConfigLocation) o; - if (this.optional != that.optional) { - return false; - } - return ObjectUtils.nullSafeEquals(this.secretBackendMetadata.getName(), that.secretBackendMetadata.getName()) - && ObjectUtils.nullSafeEquals(this.secretBackendMetadata.getPath(), - that.secretBackendMetadata.getPath()); - } - - @Override - public int hashCode() { - int result = ObjectUtils.nullSafeHashCode(this.secretBackendMetadata.getName()); - result = 31 * result + ObjectUtils.nullSafeHashCode(this.secretBackendMetadata.getPath()); - result = 31 * result + (this.optional ? 1 : 0); - return result; - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getSimpleName()); - sb.append(" [path='").append(this.secretBackendMetadata.getPath()).append('\''); - sb.append(", optional=").append(this.optional); - sb.append(']'); - return sb.toString(); - } - - private static void validatePath(String contextPath) { - Assert.isTrue(!contextPath.endsWith("/"), - () -> String.format("Location 'vault://%s' must not end with a trailing slash", contextPath)); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigOperations.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigOperations.java deleted file mode 100644 index 40352f9e..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigOperations.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.lang.Nullable; -import org.springframework.vault.core.VaultOperations; - -/** - * Interface that specified a basic set of Vault operations, implemented by - * {@link VaultConfigTemplate}. - * - * @author Mark Paluch - * @see VaultConfigTemplate - * @see Secrets - */ -public interface VaultConfigOperations { - - /** - * Read secrets from a secret backend encapsulated within a - * {@link SecretBackendMetadata}. Reading data using this method is suitable for - * secret backends that do not require a request body. - * @param secretBackendMetadata must not be {@literal null}. - * @return the configuration data. May be {@literal null}. - * @throws IllegalStateException if {@link VaultProperties#failFast} is enabled. - */ - @Nullable - Secrets read(SecretBackendMetadata secretBackendMetadata); - - /** - * @return the underlying {@link VaultOperations}. - */ - VaultOperations getVaultOperations(); - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigTemplate.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigTemplate.java deleted file mode 100644 index 1468f8fd..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigTemplate.java +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Map; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.util.Assert; -import org.springframework.vault.VaultException; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.core.util.KeyValueDelegate; -import org.springframework.vault.core.util.PropertyTransformer; -import org.springframework.vault.support.JsonMapFlattener; -import org.springframework.vault.support.VaultResponse; - -/** - * Central class to retrieve configuration from Vault. - * - * @author Mark Paluch - * @see VaultOperations - */ -public class VaultConfigTemplate implements VaultConfigOperations { - - private static final Log log = LogFactory.getLog(VaultConfigTemplate.class); - - private final VaultOperations vaultOperations; - - private final VaultProperties properties; - - private final KeyValueDelegate keyValueDelegate; - - /** - * Create a new {@link VaultConfigTemplate} given {@link VaultOperations}. - * @param vaultOperations must not be {@literal null}. - * @param properties must not be {@literal null}. - */ - public VaultConfigTemplate(VaultOperations vaultOperations, VaultProperties properties) { - - Assert.notNull(vaultOperations, "VaultOperations must not be null!"); - Assert.notNull(properties, "VaultProperties must not be null!"); - - this.vaultOperations = vaultOperations; - this.properties = properties; - this.keyValueDelegate = new KeyValueDelegate(vaultOperations); - } - - @Override - public Secrets read(SecretBackendMetadata secretBackendMetadata) { - - Assert.notNull(secretBackendMetadata, "SecureBackendAccessor must not be null!"); - - log.info(String.format("Fetching config from Vault at: %s", secretBackendMetadata.getPath())); - - try { - - VaultResponse vaultResponse; - - if (this.keyValueDelegate.isVersioned(secretBackendMetadata.getPath())) { - vaultResponse = this.keyValueDelegate.getSecret(secretBackendMetadata.getPath()); - } - else { - vaultResponse = this.vaultOperations.read(secretBackendMetadata.getPath()); - } - - if (vaultResponse == null) { - - log.info(String.format("Could not locate PropertySource: %s", "key not found")); - return null; - } - - Map data = JsonMapFlattener.flatten(vaultResponse.getRequiredData()); - PropertyTransformer propertyTransformer = secretBackendMetadata.getPropertyTransformer(); - - data = propertyTransformer.transformProperties(data); - - return createSecrets(vaultResponse, data); - } - catch (VaultException e) { - - if (this.properties.isFailFast()) { - throw new IllegalStateException( - "Could not locate PropertySource and the fail fast property is set, failing.", e); - } - else { - log.warn(String.format("Could not locate PropertySource: %s", e.getMessage())); - } - } - - return null; - } - - private Secrets createSecrets(VaultResponse vaultResponse, Map data) { - - Secrets secrets = new Secrets(); - - secrets.setData(data); - - secrets.setAuth(vaultResponse.getAuth()); - secrets.setLeaseDuration(vaultResponse.getLeaseDuration()); - secrets.setMetadata(vaultResponse.getMetadata()); - secrets.setLeaseId(vaultResponse.getLeaseId()); - secrets.setRenewable(vaultResponse.isRenewable()); - secrets.setRequestId(vaultResponse.getRequestId()); - secrets.setWarnings(vaultResponse.getWarnings()); - secrets.setWrapInfo(vaultResponse.getWrapInfo()); - - return secrets; - } - - public VaultOperations getVaultOperations() { - return this.vaultOperations; - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfiguration.java deleted file mode 100644 index 2330067b..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfiguration.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.net.URI; -import java.time.Duration; -import java.util.List; -import java.util.function.Supplier; - -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.vault.config.VaultProperties.Ssl; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.scheduling.TaskScheduler; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import org.springframework.util.StringUtils; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.LifecycleAwareSessionManager; -import org.springframework.vault.authentication.LifecycleAwareSessionManagerSupport; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.authentication.SimpleSessionManager; -import org.springframework.vault.client.ClientHttpRequestFactoryFactory; -import org.springframework.vault.client.RestTemplateBuilder; -import org.springframework.vault.client.RestTemplateCustomizer; -import org.springframework.vault.client.RestTemplateFactory; -import org.springframework.vault.client.RestTemplateRequestCustomizer; -import org.springframework.vault.client.VaultEndpoint; -import org.springframework.vault.client.VaultEndpointProvider; -import org.springframework.vault.client.VaultHttpHeaders; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.core.lease.SecretLeaseContainer; -import org.springframework.vault.support.ClientOptions; -import org.springframework.vault.support.SslConfiguration; -import org.springframework.vault.support.SslConfiguration.KeyStoreConfiguration; -import org.springframework.web.client.RestTemplate; - -/** - * Support class for Vault configuration providing utility methods. - * - * @author Mark Paluch - * @since 3.0 - */ -final class VaultConfiguration { - - private final VaultProperties vaultProperties; - - VaultConfiguration(VaultProperties vaultProperties) { - this.vaultProperties = vaultProperties; - } - - /** - * Create a {@link SslConfiguration} given {@link Ssl SSL properties}. - * @param ssl the SSL properties. - * @return the SSL configuration. - */ - static SslConfiguration createSslConfiguration(Ssl ssl) { - - KeyStoreConfiguration keyStore = KeyStoreConfiguration.unconfigured(); - KeyStoreConfiguration trustStore = KeyStoreConfiguration.unconfigured(); - - if (ssl.getKeyStore() != null) { - if (StringUtils.hasText(ssl.getKeyStorePassword())) { - keyStore = KeyStoreConfiguration.of(ssl.getKeyStore(), ssl.getKeyStorePassword().toCharArray()); - } - else { - keyStore = KeyStoreConfiguration.of(ssl.getKeyStore()); - } - - if (StringUtils.hasText(ssl.getKeyStoreType())) { - keyStore = keyStore.withStoreType(ssl.getKeyStoreType()); - } - } - - if (ssl.getTrustStore() != null) { - - if (StringUtils.hasText(ssl.getTrustStorePassword())) { - trustStore = KeyStoreConfiguration.of(ssl.getTrustStore(), ssl.getTrustStorePassword().toCharArray()); - } - else { - trustStore = KeyStoreConfiguration.of(ssl.getTrustStore()); - } - - if (StringUtils.hasText(ssl.getTrustStoreType())) { - trustStore = trustStore.withStoreType(ssl.getTrustStoreType()); - } - } - - return new SslConfiguration(keyStore, trustStore, ssl.getEnabledProtocols(), ssl.getEnabledCipherSuites()); - } - - ClientHttpRequestFactory createClientHttpRequestFactory() { - - ClientOptions clientOptions = new ClientOptions(Duration.ofMillis(this.vaultProperties.getConnectionTimeout()), - Duration.ofMillis(this.vaultProperties.getReadTimeout())); - - SslConfiguration sslConfiguration = VaultConfiguration.createSslConfiguration(this.vaultProperties.getSsl()); - - return ClientHttpRequestFactoryFactory.create(clientOptions, sslConfiguration); - } - - /** - * Create a {@link VaultEndpoint} from {@link VaultProperties}. - * @return the endpoint. - */ - VaultEndpoint createVaultEndpoint() { - - if (StringUtils.hasText(this.vaultProperties.getUri())) { - return VaultEndpoint.from(URI.create(this.vaultProperties.getUri())); - } - - VaultEndpoint vaultEndpoint = new VaultEndpoint(); - vaultEndpoint.setHost(this.vaultProperties.getHost()); - vaultEndpoint.setPort(this.vaultProperties.getPort()); - vaultEndpoint.setScheme(this.vaultProperties.getScheme()); - - return vaultEndpoint; - } - - VaultEndpoint createVaultEndpoint(ServiceInstance server) { - String fallbackScheme; - - if (StringUtils.hasText(this.vaultProperties.getUri())) { - fallbackScheme = URI.create(this.vaultProperties.getUri()).getScheme(); - } - else { - fallbackScheme = this.vaultProperties.getScheme(); - } - - VaultEndpoint vaultEndpoint = VaultEndpoint.create(server.getHost(), server.getPort()); - - if (server.getMetadata().containsKey("scheme")) { - vaultEndpoint.setScheme(server.getMetadata().get("scheme")); - } - else { - vaultEndpoint.setScheme(server.isSecure() ? "https" : fallbackScheme); - } - return vaultEndpoint; - } - - RestTemplateBuilder createRestTemplateBuilder(ClientHttpRequestFactory requestFactory, - VaultEndpointProvider endpointProvider, List customizers, - List> requestCustomizers) { - RestTemplateBuilder builder = RestTemplateBuilder.builder().requestFactory(requestFactory) - .endpointProvider(endpointProvider); - - customizers.forEach(builder::customizers); - requestCustomizers.forEach(builder::requestCustomizers); - - if (StringUtils.hasText(this.vaultProperties.getNamespace())) { - builder.defaultHeader(VaultHttpHeaders.VAULT_NAMESPACE, this.vaultProperties.getNamespace()); - } - return builder; - } - - SessionManager createSessionManager(ClientAuthentication clientAuthentication, - Supplier taskSchedulerSupplier, RestTemplateFactory restTemplateFactory) { - VaultProperties.SessionLifecycle lifecycle = this.vaultProperties.getSession().getLifecycle(); - - if (lifecycle.isEnabled()) { - RestTemplate restTemplate = restTemplateFactory.create(); - LifecycleAwareSessionManagerSupport.RefreshTrigger trigger = new LifecycleAwareSessionManagerSupport.FixedTimeoutRefreshTrigger( - lifecycle.getRefreshBeforeExpiry(), lifecycle.getExpiryThreshold()); - return new LifecycleAwareSessionManager(clientAuthentication, taskSchedulerSupplier.get(), restTemplate, - trigger); - } - - return new SimpleSessionManager(clientAuthentication); - } - - SecretLeaseContainer createSecretLeaseContainer(VaultOperations vaultOperations, - Supplier taskSchedulerSupplier) { - - VaultProperties.ConfigLifecycle lifecycle = this.vaultProperties.getConfig().getLifecycle(); - - SecretLeaseContainer container = new SecretLeaseContainer(vaultOperations, taskSchedulerSupplier.get()); - - customizeContainer(lifecycle, container); - - return container; - } - - static ThreadPoolTaskScheduler createScheduler() { - ThreadPoolTaskScheduler threadPoolTaskScheduler = new ThreadPoolTaskScheduler(); - threadPoolTaskScheduler.setPoolSize(2); - threadPoolTaskScheduler.setDaemon(true); - threadPoolTaskScheduler.setThreadNamePrefix("Spring-Cloud-Vault-"); - return threadPoolTaskScheduler; - } - - static void customizeContainer(VaultProperties.ConfigLifecycle lifecycle, SecretLeaseContainer container) { - - if (lifecycle.isEnabled()) { - - if (lifecycle.getMinRenewal() != null) { - container.setMinRenewal(lifecycle.getMinRenewal()); - } - - if (lifecycle.getExpiryThreshold() != null) { - container.setExpiryThreshold(lifecycle.getExpiryThreshold()); - } - - if (lifecycle.getLeaseEndpoints() != null) { - container.setLeaseEndpoints(lifecycle.getLeaseEndpoints()); - } - } - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigurer.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigurer.java deleted file mode 100644 index aa36e0e5..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultConfigurer.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -/** - * Defines callback methods to customize the configuration for Spring Cloud Vault - * applications. - * - *

- * Configuration classes may implement this interface to be called back and given a chance - * to customize the default configuration. Consider implementing this interface and - * overriding the relevant methods for your needs. - * - *

- * Registered bean instances of {@link VaultConfigurer} disable default secret backend - * registration for the kv and integrative (other discovered - * {@link SecretBackendMetadata}) backends. See - * {@link SecretBackendConfigurer#registerDefaultDiscoveredSecretBackends(boolean)} for - * more details. - * - * @author Mark Paluch - * @since 1.1 - * @see SecretBackendConfigurer - */ -public interface VaultConfigurer { - - /** - * Configure the secret backends that are instantiated as - * {@link org.springframework.core.env.PropertySource property sources}. - * @param configurer the {@link SecretBackendConfigurer} to configure secret backends, - * must not be {@literal null}. - */ - void addSecretBackends(SecretBackendConfigurer configurer); - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultHealthIndicator.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultHealthIndicator.java deleted file mode 100644 index cc39c595..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultHealthIndicator.java +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.boot.actuate.health.AbstractHealthIndicator; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.support.VaultHealth; - -/** - * Simple health indicator reporting Vault's availability. - * - * @author Stuart Ingram - * @author Mark Paluch - */ -public class VaultHealthIndicator extends AbstractHealthIndicator { - - private final VaultOperations vaultOperations; - - public VaultHealthIndicator(VaultOperations vaultOperations) { - this.vaultOperations = vaultOperations; - } - - @Override - protected void doHealthCheck(Builder builder) { - - VaultHealth vaultHealthResponse = this.vaultOperations.opsForSys().health(); - HealthBuilderDelegate.contributeToHealth(vaultHealthResponse, builder); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultHealthIndicatorAutoConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultHealthIndicatorAutoConfiguration.java deleted file mode 100644 index 80d6635e..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultHealthIndicatorAutoConfiguration.java +++ /dev/null @@ -1,46 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.boot.actuate.autoconfigure.health.ConditionalOnEnabledHealthIndicator; -import org.springframework.boot.actuate.autoconfigure.health.HealthContributorAutoConfiguration; -import org.springframework.boot.actuate.health.HealthIndicator; -import org.springframework.boot.autoconfigure.AutoConfigureAfter; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.context.annotation.Configuration; -import org.springframework.context.annotation.Import; - -/** - * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration - * Auto-configuration} for Vault providing beans for the application context. - * - * @author Mark Paluch - * @author Rastislav Zlacky - * @since 2.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnEnabledHealthIndicator("vault") -@ConditionalOnClass(HealthIndicator.class) -@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true) -@AutoConfigureBefore(HealthContributorAutoConfiguration.class) -@AutoConfigureAfter({ VaultAutoConfiguration.class, VaultReactiveAutoConfiguration.class }) -@Import({ VaultReactiveHealthIndicatorConfiguration.class, VaultHealthIndicatorConfiguration.class }) -public class VaultHealthIndicatorAutoConfiguration { - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultHealthIndicatorConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultHealthIndicatorConfiguration.java deleted file mode 100644 index 9ffe425a..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultHealthIndicatorConfiguration.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Map; - -import org.springframework.boot.actuate.autoconfigure.health.CompositeHealthContributorConfiguration; -import org.springframework.boot.actuate.health.HealthContributor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.vault.core.VaultOperations; - -/** - * Configuration for {@link VaultHealthIndicator}. - * - * @author Stuart Ingram - * @author Mark Paluch - * @since 1.1 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnBean(VaultOperations.class) -class VaultHealthIndicatorConfiguration - extends CompositeHealthContributorConfiguration { - - private final Map vaultTemplates; - - VaultHealthIndicatorConfiguration(Map vaultTemplates) { - super(VaultHealthIndicator::new); - this.vaultTemplates = vaultTemplates; - } - - @Bean - @ConditionalOnMissingBean(name = { "vaultHealthIndicator" }) - public HealthContributor vaultHealthIndicator() { - return createContributor(this.vaultTemplates); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultKeyValueBackendProperties.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultKeyValueBackendProperties.java deleted file mode 100644 index 4d1e4851..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultKeyValueBackendProperties.java +++ /dev/null @@ -1,194 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import jakarta.validation.constraints.NotEmpty; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.env.Environment; -import org.springframework.lang.Nullable; -import org.springframework.util.StringUtils; -import org.springframework.validation.annotation.Validated; - -/** - * Configuration properties for Vault using the key-value backend. - * - * @author Mark Paluch - * @since 2.0 - */ -@ConfigurationProperties(VaultKeyValueBackendProperties.PREFIX) -@Validated -public class VaultKeyValueBackendProperties implements EnvironmentAware, VaultKeyValueBackendPropertiesSupport { - - /** - * Configuration prefix for config properties. - */ - public static final String PREFIX = "spring.cloud.vault.kv"; - - /** - * Enable the key-value backend. - */ - private boolean enabled = true; - - /** - * Name of the default backend. - */ - @NotEmpty - private String backend = "secret"; - - /** - * Name of the default context. - */ - private String defaultContext = "application"; - - /** - * Profile-separator to combine application name and profile. - */ - @NotEmpty - private String profileSeparator = "/"; - - /** - * Application name to be used for the context. - */ - private String applicationName = "application"; - - /** - * List of active profiles. - * @since 3.0 - */ - @Nullable - private List profiles; - - /** - * Key-Value backend version. Currently supported versions are: - *

    - *
  • Version 1 (unversioned key-value backend).
  • - *
  • Version 2 (versioned key-value backend).
  • - *
- */ - private int backendVersion = 2; - - public VaultKeyValueBackendProperties() { - } - - @Override - public void setEnvironment(Environment environment) { - - String springCloudVaultAppName = environment.getProperty("spring.cloud.vault.application-name"); - - if (StringUtils.hasText(springCloudVaultAppName)) { - this.applicationName = springCloudVaultAppName; - } - else { - String springAppName = environment.getProperty("spring.application.name"); - - if (StringUtils.hasText(springAppName)) { - this.applicationName = springAppName; - } - } - - if (this.profiles == null) { - this.profiles = Arrays.asList(environment.getActiveProfiles()); - } - } - - public boolean isEnabled() { - return this.enabled; - } - - public String getBackend() { - return this.backend; - } - - public String getDefaultContext() { - return this.defaultContext; - } - - public String getProfileSeparator() { - return this.profileSeparator; - } - - public String getApplicationName() { - return this.applicationName; - } - - @Override - public List getProfiles() { - if (this.profiles == null) { - return Collections.emptyList(); - } - return Collections.unmodifiableList(new ArrayList<>(this.profiles)); - } - - @Deprecated - @DeprecatedConfigurationProperty( - reason = "Backend version no longer required. The kv version is determined during secret retrieval") - public int getBackendVersion() { - return this.backendVersion; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public void setBackend(String backend) { - this.backend = backend; - } - - public void setDefaultContext(String defaultContext) { - this.defaultContext = defaultContext; - } - - public void setProfileSeparator(String profileSeparator) { - this.profileSeparator = profileSeparator; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - public void setProfiles(List profiles) { - this.profiles = profiles; - } - - public void setBackendVersion(int backendVersion) { - this.backendVersion = backendVersion; - } - - @Override - public String toString() { - StringBuffer sb = new StringBuffer(); - sb.append(getClass().getSimpleName()); - sb.append(" [enabled=").append(this.enabled); - sb.append(", backend='").append(this.backend).append('\''); - sb.append(", defaultContext='").append(this.defaultContext).append('\''); - sb.append(", profileSeparator='").append(this.profileSeparator).append('\''); - sb.append(", applicationName='").append(this.applicationName).append('\''); - sb.append(", profiles='").append(this.profiles).append('\''); - sb.append(", backendVersion=").append(this.backendVersion); - sb.append(']'); - return sb.toString(); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultKeyValueBackendPropertiesSupport.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultKeyValueBackendPropertiesSupport.java deleted file mode 100644 index 8beec656..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultKeyValueBackendPropertiesSupport.java +++ /dev/null @@ -1,61 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.List; - -/** - * Interface declaring Key-Value configuration properties. - * - * @author Mark Paluch - * @since 2.0 - */ -public interface VaultKeyValueBackendPropertiesSupport { - - /** - * @return {@literal true} if this backend configuration is enabled; {@literal false} - * otherwise. - */ - boolean isEnabled(); - - /** - * @return mound path of the secret backend. - */ - String getBackend(); - - /** - * @return default context path. Can be empty. - */ - String getDefaultContext(); - - /** - * @return profile separator character. - */ - String getProfileSeparator(); - - /** - * @return the application name to use. - */ - String getApplicationName(); - - /** - * @return the application profiles to use. - * @since 3.0 - */ - List getProfiles(); - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultObservationAutoConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultObservationAutoConfiguration.java deleted file mode 100644 index 13875046..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultObservationAutoConfiguration.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright 2016-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationRegistry; - -import org.springframework.boot.actuate.metrics.web.client.ObservationRestTemplateCustomizer; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.observation.DefaultClientRequestObservationConvention; -import org.springframework.vault.client.RestTemplateCustomizer; - -/** - * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration - * Auto-configuration} for Observability. - * - * @author Mark Paluch - * @since 3.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(Observation.class) -@AutoConfigureBefore(VaultAutoConfiguration.class) -public class VaultObservationAutoConfiguration { - - @Bean - @ConditionalOnSingleCandidate(ObservationRegistry.class) - public RestTemplateCustomizer observationVaultRestTemplateCustomizer(ObservationRegistry observationRegistry) { - return restTemplate -> new ObservationRestTemplateCustomizer(observationRegistry, - new DefaultClientRequestObservationConvention()).customize(restTemplate); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultProperties.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultProperties.java deleted file mode 100644 index 5e123a89..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultProperties.java +++ /dev/null @@ -1,1369 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.net.URI; -import java.time.Duration; -import java.util.ArrayList; -import java.util.List; - -import org.springframework.boot.context.properties.ConfigurationProperties; -import org.springframework.boot.context.properties.DeprecatedConfigurationProperty; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.env.Environment; -import org.springframework.core.io.Resource; -import org.springframework.lang.Nullable; -import org.springframework.util.StringUtils; -import org.springframework.vault.authentication.AzureMsiAuthenticationOptions; -import org.springframework.vault.authentication.LoginToken; -import org.springframework.vault.core.lease.LeaseEndpoints; - -/** - * Properties to configure Vault support. - * - * @author Spencer Gibb - * @author Mark Paluch - * @author Kevin Holditch - * @author Michal Budzyn - * @author Grenville Wilson - * @author Mårten Svantesson - */ -@ConfigurationProperties(VaultProperties.PREFIX) -public class VaultProperties implements EnvironmentAware { - - /** - * Configuration prefix for config properties. - */ - public static final String PREFIX = "spring.cloud.vault"; - - /** - * Enable Vault config server. - */ - private boolean enabled = true; - - /** - * Vault server host. - */ - private String host = "localhost"; - - /** - * Vault server port. - */ - private int port = 8200; - - /** - * Protocol scheme. Can be either "http" or "https". - */ - private String scheme = "https"; - - /** - * Vault URI. Can be set with scheme, host and port. - */ - @Nullable - private String uri; - - /** - * Vault namespace (requires Vault Enterprise). - */ - @Nullable - private String namespace; - - /** - * Reactive properties. - */ - private Reactive reactive = new Reactive(); - - /** - * Discovery properties. - */ - private Discovery discovery = new Discovery(); - - /** - * Connection timeout. - */ - private int connectionTimeout = 5000; - - /** - * Read timeout. - */ - private int readTimeout = 15000; - - /** - * Fail fast if data cannot be obtained from Vault. - */ - private boolean failFast = false; - - /** - * Static vault token. Required if {@link #authentication} is {@code TOKEN}. - */ - @Nullable - private String token; - - private AppIdProperties appId = new AppIdProperties(); - - private AppRoleProperties appRole = new AppRoleProperties(); - - private AwsEc2Properties awsEc2 = new AwsEc2Properties(); - - private AwsIamProperties awsIam = new AwsIamProperties(); - - private AzureMsiProperties azureMsi = new AzureMsiProperties(); - - private GcpGceProperties gcpGce = new GcpGceProperties(); - - private GcpIamProperties gcpIam = new GcpIamProperties(); - - private KubernetesProperties kubernetes = new KubernetesProperties(); - - private PcfProperties pcf = new PcfProperties(); - - private Ssl ssl = new Ssl(); - - private Config config = new Config(); - - private Session session = new Session(); - - /** - * Application name for AppId authentication. - */ - private String applicationName = "application"; - - private AuthenticationMethod authentication = AuthenticationMethod.TOKEN; - - @Override - public void setEnvironment(Environment environment) { - - String springAppName = environment.getProperty("spring.application.name"); - - if (StringUtils.hasText(springAppName)) { - this.applicationName = springAppName; - } - } - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public String getHost() { - return this.host; - } - - public void setHost(String host) { - this.host = host; - } - - public int getPort() { - return this.port; - } - - public void setPort(int port) { - this.port = port; - } - - public String getScheme() { - return this.scheme; - } - - public void setScheme(String scheme) { - this.scheme = scheme; - } - - @Nullable - public String getUri() { - return this.uri; - } - - public void setUri(@Nullable String uri) { - this.uri = uri; - } - - @Nullable - public String getNamespace() { - return this.namespace; - } - - public void setNamespace(@Nullable String namespace) { - this.namespace = namespace; - } - - public Reactive getReactive() { - return this.reactive; - } - - public void setReactive(Reactive reactive) { - this.reactive = reactive; - } - - public Discovery getDiscovery() { - return this.discovery; - } - - public void setDiscovery(Discovery discovery) { - this.discovery = discovery; - } - - public int getConnectionTimeout() { - return this.connectionTimeout; - } - - public void setConnectionTimeout(int connectionTimeout) { - this.connectionTimeout = connectionTimeout; - } - - public int getReadTimeout() { - return this.readTimeout; - } - - public void setReadTimeout(int readTimeout) { - this.readTimeout = readTimeout; - } - - public boolean isFailFast() { - return this.failFast; - } - - public void setFailFast(boolean failFast) { - this.failFast = failFast; - } - - @Nullable - public String getToken() { - return this.token; - } - - public void setToken(@Nullable String token) { - this.token = token; - } - - public AppIdProperties getAppId() { - return this.appId; - } - - public void setAppId(AppIdProperties appId) { - this.appId = appId; - } - - public AppRoleProperties getAppRole() { - return this.appRole; - } - - public void setAppRole(AppRoleProperties appRole) { - this.appRole = appRole; - } - - public AwsEc2Properties getAwsEc2() { - return this.awsEc2; - } - - public void setAwsEc2(AwsEc2Properties awsEc2) { - this.awsEc2 = awsEc2; - } - - public AwsIamProperties getAwsIam() { - return this.awsIam; - } - - public void setAwsIam(AwsIamProperties awsIam) { - this.awsIam = awsIam; - } - - public AzureMsiProperties getAzureMsi() { - return this.azureMsi; - } - - public void setAzureMsi(AzureMsiProperties azureMsi) { - this.azureMsi = azureMsi; - } - - public GcpGceProperties getGcpGce() { - return this.gcpGce; - } - - public void setGcpGce(GcpGceProperties gcpGce) { - this.gcpGce = gcpGce; - } - - public GcpIamProperties getGcpIam() { - return this.gcpIam; - } - - public void setGcpIam(GcpIamProperties gcpIam) { - this.gcpIam = gcpIam; - } - - public KubernetesProperties getKubernetes() { - return this.kubernetes; - } - - public void setKubernetes(KubernetesProperties kubernetes) { - this.kubernetes = kubernetes; - } - - public PcfProperties getPcf() { - return this.pcf; - } - - public void setPcf(PcfProperties pcf) { - this.pcf = pcf; - } - - public Ssl getSsl() { - return this.ssl; - } - - public void setSsl(Ssl ssl) { - this.ssl = ssl; - } - - public Config getConfig() { - return this.config; - } - - public void setConfig(Config config) { - this.config = config; - } - - public Session getSession() { - return this.session; - } - - public void setSession(Session session) { - this.session = session; - } - - public String getApplicationName() { - return this.applicationName; - } - - public void setApplicationName(String applicationName) { - this.applicationName = applicationName; - } - - public AuthenticationMethod getAuthentication() { - return this.authentication; - } - - public void setAuthentication(AuthenticationMethod authentication) { - this.authentication = authentication; - } - - /** - * Enumeration of authentication methods. - */ - public enum AuthenticationMethod { - - APPID, APPROLE, AWS_EC2, AWS_IAM, AZURE_MSI, CERT, CUBBYHOLE, GCP_GCE, GCP_IAM, KUBERNETES, NONE, PCF, TOKEN; - - } - - /** - * Reactive properties. - * - * @since 3.0.5 - */ - public static class Reactive { - - /** - * Flag to indicate that reactive discovery is enabled - */ - private boolean enabled = true; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - } - - /** - * Discovery properties. - */ - public static class Discovery { - - /** - * Default service Id. - */ - public static final String DEFAULT_VAULT = "vault"; - - /** - * Flag to indicate that Vault server discovery is enabled (vault server URL will - * be looked up via discovery). - */ - private boolean enabled; - - /** - * Service id to locate Vault. - */ - private String serviceId = DEFAULT_VAULT; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public String getServiceId() { - return this.serviceId; - } - - public void setServiceId(String serviceId) { - this.serviceId = serviceId; - } - - } - - /** - * AppId properties. - */ - public static class AppIdProperties { - - /** - * Property value for UserId generation using a Mac-Address. - * - * @see org.springframework.vault.authentication.MacAddressUserId - */ - public static final String MAC_ADDRESS = "MAC_ADDRESS"; - - /** - * Property value for UserId generation using an IP-Address. - * - * @see org.springframework.vault.authentication.IpAddressUserId - */ - public static final String IP_ADDRESS = "IP_ADDRESS"; - - /** - * Mount path of the AppId authentication backend. - */ - private String appIdPath = "app-id"; - - /** - * Network interface hint for the "MAC_ADDRESS" UserId mechanism. - */ - @Nullable - private String networkInterface; - - /** - * UserId mechanism. Can be either "MAC_ADDRESS", "IP_ADDRESS", a string or a - * class name. - */ - private String userId = MAC_ADDRESS; - - public String getAppIdPath() { - return this.appIdPath; - } - - public void setAppIdPath(String appIdPath) { - this.appIdPath = appIdPath; - } - - @Nullable - public String getNetworkInterface() { - return this.networkInterface; - } - - public void setNetworkInterface(@Nullable String networkInterface) { - this.networkInterface = networkInterface; - } - - public String getUserId() { - return this.userId; - } - - public void setUserId(String userId) { - this.userId = userId; - } - - } - - /** - * AppRole properties. - */ - public static class AppRoleProperties { - - /** - * Mount path of the AppRole authentication backend. - */ - private String appRolePath = "approle"; - - /** - * Name of the role, optional, used for pull-mode. - */ - private String role = ""; - - /** - * The RoleId. - */ - @Nullable - private String roleId; - - /** - * The SecretId. - */ - @Nullable - private String secretId; - - public String getAppRolePath() { - return this.appRolePath; - } - - public void setAppRolePath(String appRolePath) { - this.appRolePath = appRolePath; - } - - public String getRole() { - return this.role; - } - - public void setRole(String role) { - this.role = role; - } - - @Nullable - public String getRoleId() { - return this.roleId; - } - - public void setRoleId(@Nullable String roleId) { - this.roleId = roleId; - } - - @Nullable - public String getSecretId() { - return this.secretId; - } - - public void setSecretId(@Nullable String secretId) { - this.secretId = secretId; - } - - } - - /** - * AWS-EC2 properties. - */ - public static class AwsEc2Properties { - - /** - * URL of the AWS-EC2 PKCS7 identity document. - */ - private URI identityDocument = URI.create("http://169.254.169.254/latest/dynamic/instance-identity/pkcs7"); - - /** - * Mount path of the AWS-EC2 authentication backend. - */ - private String awsEc2Path = "aws-ec2"; - - /** - * Name of the role, optional. - */ - private String role = ""; - - /** - * Nonce used for AWS-EC2 authentication. An empty nonce defaults to nonce - * generation. - */ - @Nullable - private String nonce; - - public URI getIdentityDocument() { - return this.identityDocument; - } - - public void setIdentityDocument(URI identityDocument) { - this.identityDocument = identityDocument; - } - - public String getAwsEc2Path() { - return this.awsEc2Path; - } - - public void setAwsEc2Path(String awsEc2Path) { - this.awsEc2Path = awsEc2Path; - } - - public String getRole() { - return this.role; - } - - public void setRole(String role) { - this.role = role; - } - - @Nullable - public String getNonce() { - return this.nonce; - } - - public void setNonce(@Nullable String nonce) { - this.nonce = nonce; - } - - } - - /** - * AWS-IAM properties. - */ - public static class AwsIamProperties { - - /** - * Mount path of the AWS authentication backend. - */ - private String awsPath = "aws"; - - /** - * Name of the region, optional. Inferred by AWS defaults if not set. - * @since 4.0.1 - */ - private String region = ""; - - /** - * Name of the role, optional. Defaults to the friendly IAM name if not set. - */ - private String role = ""; - - /** - * Name of the server used to set {@code X-Vault-AWS-IAM-Server-ID} header in the - * headers of login requests. - */ - @Nullable - private String serverName; - - /** - * STS server URI. - * - * @since 2.2 - */ - @Nullable - private URI endpointUri; - - public String getAwsPath() { - return this.awsPath; - } - - public String getRegion() { - return this.region; - } - - public String getRole() { - return this.role; - } - - @Nullable - public String getServerName() { - return this.serverName; - } - - public void setAwsPath(String awsPath) { - this.awsPath = awsPath; - } - - public void setRegion(String region) { - this.region = region; - } - - public void setRole(String role) { - this.role = role; - } - - public void setServerName(String serverName) { - this.serverName = serverName; - } - - @Nullable - public URI getEndpointUri() { - return this.endpointUri; - } - - public void setEndpointUri(URI endpointUri) { - this.endpointUri = endpointUri; - } - - } - - /** - * Azure MSI properties. - */ - public static class AzureMsiProperties { - - /** - * Mount path of the Azure MSI authentication backend. - */ - private String azurePath = "azure"; - - /** - * Name of the role. - */ - private String role = ""; - - /** - * Instance metadata service URI. - * - * @since 3.0 - */ - private URI metadataService = AzureMsiAuthenticationOptions.DEFAULT_INSTANCE_METADATA_SERVICE_URI; - - /** - * Identity token service URI. - * - * @since 3.0 - */ - private URI identityTokenService = AzureMsiAuthenticationOptions.DEFAULT_IDENTITY_TOKEN_SERVICE_URI; - - public String getAzurePath() { - return this.azurePath; - } - - public void setAzurePath(String azurePath) { - this.azurePath = azurePath; - } - - public String getRole() { - return this.role; - } - - public void setRole(String role) { - this.role = role; - } - - public URI getMetadataService() { - return this.metadataService; - } - - public void setMetadataService(URI metadataService) { - this.metadataService = metadataService; - } - - public URI getIdentityTokenService() { - return this.identityTokenService; - } - - public void setIdentityTokenService(URI identityTokenService) { - this.identityTokenService = identityTokenService; - } - - } - - /** - * GCP-GCE properties. - */ - public static class GcpGceProperties { - - /** - * Mount path of the Kubernetes authentication backend. - */ - private String gcpPath = "gcp"; - - /** - * Name of the role against which the login is being attempted. - */ - private String role = ""; - - /** - * Optional service account id. Using the default id if left unconfigured. - */ - private String serviceAccount = ""; - - public String getGcpPath() { - return this.gcpPath; - } - - public String getRole() { - return this.role; - } - - public String getServiceAccount() { - return this.serviceAccount; - } - - public void setGcpPath(String gcpPath) { - this.gcpPath = gcpPath; - } - - public void setRole(String role) { - this.role = role; - } - - public void setServiceAccount(String serviceAccount) { - this.serviceAccount = serviceAccount; - } - - } - - /** - * GCP-IAM properties. - */ - public static class GcpIamProperties { - - /** - * Credentials configuration. - */ - private final GcpCredentials credentials = new GcpCredentials(); - - /** - * Mount path of the Kubernetes authentication backend. - */ - private String gcpPath = "gcp"; - - /** - * Name of the role against which the login is being attempted. - */ - private String role = ""; - - /** - * Overrides the GCP project Id. - */ - private String projectId = ""; - - /** - * Overrides the GCP service account Id. - */ - private String serviceAccountId = ""; - - /** - * Validity of the JWT token. - */ - private Duration jwtValidity = Duration.ofMinutes(15); - - public GcpCredentials getCredentials() { - return this.credentials; - } - - public String getGcpPath() { - return this.gcpPath; - } - - public String getRole() { - return this.role; - } - - public String getProjectId() { - return this.projectId; - } - - public String getServiceAccountId() { - return this.serviceAccountId; - } - - public Duration getJwtValidity() { - return this.jwtValidity; - } - - public void setGcpPath(String gcpPath) { - this.gcpPath = gcpPath; - } - - public void setRole(String role) { - this.role = role; - } - - public void setProjectId(String projectId) { - this.projectId = projectId; - } - - public void setServiceAccountId(String serviceAccountId) { - this.serviceAccountId = serviceAccountId; - } - - public void setJwtValidity(Duration jwtValidity) { - this.jwtValidity = jwtValidity; - } - - } - - /** - * GCP credential properties. - */ - public static class GcpCredentials { - - /** - * Location of the OAuth2 credentials private key. - * - *

- * Since this is a Resource, the private key can be in a multitude of locations, - * such as a local file system, classpath, URL, etc. - */ - private Resource location; - - /** - * The base64 encoded contents of an OAuth2 account private key in JSON format. - */ - private String encodedKey; - - public Resource getLocation() { - return this.location; - } - - public String getEncodedKey() { - return this.encodedKey; - } - - public void setLocation(Resource location) { - this.location = location; - } - - public void setEncodedKey(String encodedKey) { - this.encodedKey = encodedKey; - } - - } - - /** - * Kubernetes properties. - */ - public static class KubernetesProperties { - - /** - * Mount path of the Kubernetes authentication backend. - */ - private String kubernetesPath = "kubernetes"; - - /** - * Name of the role against which the login is being attempted. - */ - private String role = ""; - - /** - * Path to the service account token file. - */ - private String serviceAccountTokenFile = "/var/run/secrets/kubernetes.io/serviceaccount/token"; - - public String getKubernetesPath() { - return this.kubernetesPath; - } - - public String getRole() { - return this.role; - } - - public String getServiceAccountTokenFile() { - return this.serviceAccountTokenFile; - } - - public void setKubernetesPath(String kubernetesPath) { - this.kubernetesPath = kubernetesPath; - } - - public void setRole(String role) { - this.role = role; - } - - public void setServiceAccountTokenFile(String serviceAccountTokenFile) { - this.serviceAccountTokenFile = serviceAccountTokenFile; - } - - } - - /** - * PCF properties. - */ - public static class PcfProperties { - - /** - * Mount path of the Kubernetes authentication backend. - */ - private String pcfPath = "pcf"; - - /** - * Name of the role against which the login is being attempted. - */ - private String role = ""; - - /** - * Path to the instance certificate (PEM). Defaults to {@code CF_INSTANCE_CERT} - * env variable. - */ - @Nullable - private Resource instanceCertificate; - - /** - * Path to the instance key (PEM). Defaults to {@code CF_INSTANCE_KEY} env - * variable. - */ - @Nullable - private Resource instanceKey; - - public String getPcfPath() { - return this.pcfPath; - } - - public void setPcfPath(String pcfPath) { - this.pcfPath = pcfPath; - } - - public String getRole() { - return this.role; - } - - public void setRole(String role) { - this.role = role; - } - - @Nullable - public Resource getInstanceCertificate() { - return this.instanceCertificate; - } - - public void setInstanceCertificate(@Nullable Resource instanceCertificate) { - this.instanceCertificate = instanceCertificate; - } - - @Nullable - public Resource getInstanceKey() { - return this.instanceKey; - } - - public void setInstanceKey(@Nullable Resource instanceKey) { - this.instanceKey = instanceKey; - } - - } - - /** - * SSL properties. - */ - public static class Ssl { - - /** - * Trust store that holds certificates and private keys. - */ - @Nullable - private Resource keyStore; - - /** - * Password used to access the key store. - */ - @Nullable - private String keyStorePassword; - - /** - * Type of the key store. - * - * @since 3.0 - */ - @Nullable - private String keyStoreType; - - /** - * Trust store that holds SSL certificates. - */ - @Nullable - private Resource trustStore; - - /** - * Password used to access the trust store. - */ - @Nullable - private String trustStorePassword; - - /** - * Type of the trust store. - * - * @since 3.0 - */ - @Nullable - private String trustStoreType; - - /** - * Mount path of the TLS cert authentication backend. - */ - private String certAuthPath = "cert"; - - /** - * List of enabled SSL/TLS protocol. - * @since 3.0.2 - */ - private List enabledProtocols = new ArrayList<>(); - - /** - * List of enabled SSL/TLS cipher suites. - * @since 3.0.2 - */ - private List enabledCipherSuites = new ArrayList<>(); - - @Nullable - public Resource getKeyStore() { - return this.keyStore; - } - - public void setKeyStore(@Nullable Resource keyStore) { - this.keyStore = keyStore; - } - - @Nullable - public String getKeyStorePassword() { - return this.keyStorePassword; - } - - public void setKeyStorePassword(@Nullable String keyStorePassword) { - this.keyStorePassword = keyStorePassword; - } - - @Nullable - public String getKeyStoreType() { - return this.keyStoreType; - } - - public void setKeyStoreType(@Nullable String keyStoreType) { - this.keyStoreType = keyStoreType; - } - - @Nullable - public Resource getTrustStore() { - return this.trustStore; - } - - public void setTrustStore(@Nullable Resource trustStore) { - this.trustStore = trustStore; - } - - @Nullable - public String getTrustStorePassword() { - return this.trustStorePassword; - } - - public void setTrustStorePassword(@Nullable String trustStorePassword) { - this.trustStorePassword = trustStorePassword; - } - - @Nullable - public String getTrustStoreType() { - return this.trustStoreType; - } - - public void setTrustStoreType(@Nullable String trustStoreType) { - this.trustStoreType = trustStoreType; - } - - public String getCertAuthPath() { - return this.certAuthPath; - } - - public void setCertAuthPath(String certAuthPath) { - this.certAuthPath = certAuthPath; - } - - public List getEnabledProtocols() { - return this.enabledProtocols; - } - - public void setEnabledProtocols(List enabledProtocols) { - this.enabledProtocols = enabledProtocols; - } - - public List getEnabledCipherSuites() { - return this.enabledCipherSuites; - } - - public void setEnabledCipherSuites(List enabledCipherSuites) { - this.enabledCipherSuites = enabledCipherSuites; - } - - } - - /** - * Property source properties. - */ - public static class Config { - - /** - * Used to set a {@link org.springframework.core.env.PropertySource} priority. - * This is useful to use Vault as an override on other property sources. - * - * @see org.springframework.core.PriorityOrdered - */ - private int order = 0; - - private ConfigLifecycle lifecycle = new ConfigLifecycle(); - - @DeprecatedConfigurationProperty(reason = "Only required for deprecated Bootstrap Context usage") - public int getOrder() { - return this.order; - } - - public ConfigLifecycle getLifecycle() { - return this.lifecycle; - } - - public void setOrder(int order) { - this.order = order; - } - - public void setLifecycle(ConfigLifecycle lifecycle) { - this.lifecycle = lifecycle; - } - - } - - /** - * Configuration to Vault lifecycle management (renewal, revocation of tokens and - * secrets). - */ - public static class ConfigLifecycle { - - /** - * Enable lifecycle management. - */ - private boolean enabled = true; - - /** - * The time period that is at least required before renewing a lease. - * - * @since 2.2 - */ - @Nullable - private Duration minRenewal; - - /** - * The expiry threshold. {@link Lease} is renewed the given {@link Duration} - * before it expires. - * - * @since 2.2 - */ - @Nullable - private Duration expiryThreshold; - - /** - * Set the {@link LeaseEndpoints} to delegate renewal/revocation calls to. - * {@link LeaseEndpoints} encapsulates differences between Vault versions that - * affect the location of renewal/revocation endpoints. - * - * Can be {@link LeaseEndpoints#SysLeases} for version 0.8 or above of Vault or - * {@link LeaseEndpoints#Legacy} for older versions (the default). - * - * @since 2.2 - */ - @Nullable - private LeaseEndpoints leaseEndpoints; - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - @Nullable - public Duration getMinRenewal() { - return this.minRenewal; - } - - public void setMinRenewal(@Nullable Duration minRenewal) { - this.minRenewal = minRenewal; - } - - @Nullable - public Duration getExpiryThreshold() { - return this.expiryThreshold; - } - - public void setExpiryThreshold(@Nullable Duration expiryThreshold) { - this.expiryThreshold = expiryThreshold; - } - - @Nullable - public LeaseEndpoints getLeaseEndpoints() { - return this.leaseEndpoints; - } - - public void setLeaseEndpoints(@Nullable LeaseEndpoints leaseEndpoints) { - this.leaseEndpoints = leaseEndpoints; - } - - } - - /** - * Session management configuration properties. - * - * @since 3.0 - */ - public static class Session { - - private SessionLifecycle lifecycle = new SessionLifecycle(); - - public SessionLifecycle getLifecycle() { - return this.lifecycle; - } - - public void setLifecycle(SessionLifecycle lifecycle) { - this.lifecycle = lifecycle; - } - - } - - /** - * Configuration to Vault Session lifecycle management. - * - * @since 3.0 - */ - public static class SessionLifecycle { - - /** - * Enable session lifecycle management. - */ - private boolean enabled = true; - - /** - * The time period that is at least required before renewing the - * {@link LoginToken}. - */ - private Duration refreshBeforeExpiry = Duration.ofSeconds(5); - - /** - * The expiry threshold for a {@link LoginToken}. The threshold represents a - * minimum TTL duration to consider a login token as valid. Tokens with a shorter - * TTL are considered expired and are not used anymore. Should be greater than - * {@code refreshBeforeExpiry} to prevent token expiry. - */ - private Duration expiryThreshold = Duration.ofSeconds(7); - - public boolean isEnabled() { - return this.enabled; - } - - public void setEnabled(boolean enabled) { - this.enabled = enabled; - } - - public Duration getRefreshBeforeExpiry() { - return this.refreshBeforeExpiry; - } - - public void setRefreshBeforeExpiry(Duration refreshBeforeExpiry) { - this.refreshBeforeExpiry = refreshBeforeExpiry; - } - - public Duration getExpiryThreshold() { - return this.expiryThreshold; - } - - public void setExpiryThreshold(Duration expiryThreshold) { - this.expiryThreshold = expiryThreshold; - } - - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultPropertySource.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultPropertySource.java deleted file mode 100644 index 45821436..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultPropertySource.java +++ /dev/null @@ -1,102 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; - -import org.springframework.core.env.EnumerablePropertySource; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; - -/** - * A {@link EnumerablePropertySource} backed by {@link VaultConfigTemplate}. - * - * @author Spencer Gibb - * @author Mark Paluch - */ -class VaultPropertySource extends EnumerablePropertySource { - - private static final Log log = LogFactory.getLog(VaultPropertySource.class); - - private final boolean failFast; - - private final SecretBackendMetadata secretBackendMetadata; - - private final Map properties = new LinkedHashMap<>(); - - @Nullable - private Secrets secrets; - - /** - * Creates a new {@link VaultPropertySource}. - * @param operations must not be {@literal null}. - * @param failFast fail if properties could not be read because of access errors. - * @param secretBackendMetadata must not be {@literal null}. - */ - VaultPropertySource(VaultConfigOperations operations, boolean failFast, - SecretBackendMetadata secretBackendMetadata) { - - super(secretBackendMetadata.getName(), operations); - - Assert.notNull(operations, "VaultConfigTemplate must not be null!"); - Assert.notNull(secretBackendMetadata, "SecretBackendMetadata must not be null!"); - - this.failFast = failFast; - this.secretBackendMetadata = secretBackendMetadata; - } - - /** - * Initialize property source and read properties from Vault. - */ - public void init() { - - try { - this.secrets = this.source.read(this.secretBackendMetadata); - if (this.secrets != null) { - this.properties.putAll(this.secrets.getRequiredData()); - } - } - catch (RuntimeException e) { - - String message = String.format("Unable to read properties from Vault using %s for %s ", getName(), - this.secretBackendMetadata.getVariables()); - - if (this.failFast) { - throw e; - } - - log.error(message, e); - } - } - - @Override - public Object getProperty(String name) { - return this.properties.get(name); - } - - @Override - public String[] getPropertyNames() { - Set strings = this.properties.keySet(); - return strings.toArray(new String[0]); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultPropertySourceLocator.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultPropertySourceLocator.java deleted file mode 100644 index b4827ddf..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultPropertySourceLocator.java +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.cloud.bootstrap.config.PropertySourceLocator; -import org.springframework.core.PriorityOrdered; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.PropertySource; -import org.springframework.util.Assert; - -/** - * {@link PropertySourceLocator} using {@link VaultConfigTemplate}. - * - * @author Spencer Gibb - * @author Mark Paluch - * @author Jean-Philippe Bélanger - * @author Ryan Hoegg - */ -class VaultPropertySourceLocator extends VaultPropertySourceLocatorSupport implements PriorityOrdered { - - private final VaultConfigOperations operations; - - private final VaultProperties properties; - - /** - * Creates a new {@link VaultPropertySourceLocator}. - * @param operations must not be {@literal null}. - * @param properties must not be {@literal null}. - * @param propertySourceLocatorConfiguration must not be {@literal null}. - * @since 1.1 - */ - VaultPropertySourceLocator(VaultConfigOperations operations, VaultProperties properties, - PropertySourceLocatorConfiguration propertySourceLocatorConfiguration) { - - super("vault", propertySourceLocatorConfiguration); - - Assert.notNull(operations, "VaultConfigOperations must not be null"); - Assert.notNull(properties, "VaultProperties must not be null"); - - this.operations = operations; - this.properties = properties; - } - - @Override - public int getOrder() { - return this.properties.getConfig().getOrder(); - } - - /** - * Initialize nested {@link PropertySource}s inside the - * {@link CompositePropertySource}. - * @param propertySource the {@link CompositePropertySource} to initialize. - */ - protected void initialize(CompositePropertySource propertySource) { - - for (PropertySource source : propertySource.getPropertySources()) { - ((VaultPropertySource) source).init(); - } - } - - /** - * Create {@link VaultPropertySource} initialized with a {@link SecretBackendMetadata} - * . - * @param accessor the {@link SecretBackendMetadata}. - * @return the {@link VaultPropertySource} to use. - */ - protected PropertySource createVaultPropertySource(SecretBackendMetadata accessor) { - return new VaultPropertySource(this.operations, this.properties.isFailFast(), accessor); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorSupport.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorSupport.java deleted file mode 100644 index 22304330..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorSupport.java +++ /dev/null @@ -1,251 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; - -import org.springframework.cloud.bootstrap.config.PropertySourceLocator; -import org.springframework.context.EnvironmentAware; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.Environment; -import org.springframework.core.env.PropertySource; -import org.springframework.util.Assert; - -/** - * Abstract {@link PropertySourceLocator} to create {@link PropertySource}s based on - * {@link VaultKeyValueBackendProperties} and {@link SecretBackendMetadata}. - * - * @author Mark Paluch - */ -public abstract class VaultPropertySourceLocatorSupport implements PropertySourceLocator { - - private final String propertySourceName; - - private final PropertySourceLocatorConfiguration propertySourceLocatorConfiguration; - - /** - * Creates a new {@link VaultPropertySourceLocatorSupport} given a - * {@link PropertySourceLocatorConfiguration}. - * @param propertySourceName must not be {@literal null} or empty. - * @param propertySourceLocatorConfiguration must not be {@literal null}. - * @since 1.1 - */ - public VaultPropertySourceLocatorSupport(String propertySourceName, - PropertySourceLocatorConfiguration propertySourceLocatorConfiguration) { - - Assert.hasText(propertySourceName, "PropertySource name must not be empty"); - Assert.notNull(propertySourceLocatorConfiguration, "PropertySourceLocatorConfiguration must not be null"); - - this.propertySourceName = propertySourceName; - this.propertySourceLocatorConfiguration = propertySourceLocatorConfiguration; - } - - static PropertySourceLocatorConfiguration createConfiguration(VaultKeyValueBackendProperties kvBackendProperties) { - - Assert.notNull(kvBackendProperties, "VaultKeyValueBackendProperties must not be null"); - - return new KeyValuePropertySourceLocatorConfiguration(kvBackendProperties); - } - - @Override - public PropertySource locate(Environment environment) { - - if (this.propertySourceLocatorConfiguration instanceof EnvironmentAware) { - ((EnvironmentAware) this.propertySourceLocatorConfiguration).setEnvironment(environment); - } - - CompositePropertySource propertySource = createCompositePropertySource(environment); - initialize(propertySource); - - return propertySource; - } - - // ------------------------------------------------------------------------- - // Implementation hooks and helper methods - // ------------------------------------------------------------------------- - - /** - * Allows initialization the {@link PropertySource} before use. Implementations may - * override this method to preload properties in the {@link PropertySource}. - * @param propertySource must not be {@literal null}. - */ - protected void initialize(CompositePropertySource propertySource) { - } - - /** - * Creates a {@link CompositePropertySource}. - * @param environment must not be {@literal null}. - * @return the composite {@link PropertySource}. - */ - protected CompositePropertySource createCompositePropertySource(Environment environment) { - - List> propertySources = doCreatePropertySources(environment); - - return doCreateCompositePropertySource(this.propertySourceName, propertySources); - } - - /** - * Create {@link PropertySource}s given {@link Environment} from the property - * configuration. - * @param environment must not be {@literal null}. - * @return a {@link List} of ordered {@link PropertySource}s. - */ - protected List> doCreatePropertySources(Environment environment) { - - Collection secretBackends = this.propertySourceLocatorConfiguration.getSecretBackends(); - List sorted = new ArrayList<>(secretBackends); - - AnnotationAwareOrderComparator.sort(sorted); - - List> propertySources = new ArrayList<>(doCreateKeyValuePropertySources(environment)); - - for (SecretBackendMetadata backendAccessor : sorted) { - PropertySource vaultPropertySource = createVaultPropertySource(backendAccessor); - propertySources.add(vaultPropertySource); - } - - return propertySources; - } - - /** - * Create {@link PropertySource}s using the kv {@literal secret} backend. Property - * sources for the kv secret backend derive from the application name and active - * profiles to generate context paths. - * @param environment must not be {@literal null}. - * @return {@link List} of {@link PropertySource}s. - */ - protected List> doCreateKeyValuePropertySources(Environment environment) { - return new ArrayList<>(); - } - - /** - * Create a {@link CompositePropertySource} given a {@link List} of - * {@link PropertySource}s. - * @param propertySourceName the property source name. - * @param propertySources the property sources. - * @return the {@link CompositePropertySource} to use. - */ - protected CompositePropertySource doCreateCompositePropertySource(String propertySourceName, - List> propertySources) { - - CompositePropertySource compositePropertySource = new CompositePropertySource(propertySourceName); - - for (PropertySource propertySource : propertySources) { - compositePropertySource.addPropertySource(propertySource); - } - - return compositePropertySource; - } - - /** - * Create {@link VaultPropertySource} initialized with a {@link SecretBackendMetadata} - * . - * @param accessor the {@link SecretBackendMetadata}. - * @return the {@link VaultPropertySource} to use. - */ - protected abstract PropertySource createVaultPropertySource(SecretBackendMetadata accessor); - - private static class KeyValuePropertySourceLocatorConfiguration implements PropertySourceLocatorConfiguration { - - private final VaultKeyValueBackendPropertiesSupport keyValueBackendProperties; - - KeyValuePropertySourceLocatorConfiguration(VaultKeyValueBackendPropertiesSupport keyValueBackendProperties) { - this.keyValueBackendProperties = keyValueBackendProperties; - } - - @Override - public Collection getSecretBackends() { - - if (this.keyValueBackendProperties.isEnabled()) { - - List contexts = KeyValueSecretBackendMetadata.buildContexts(this.keyValueBackendProperties, - this.keyValueBackendProperties.getProfiles()); - - List result = new ArrayList<>(contexts.size()); - - for (String context : contexts) { - result.add( - KeyValueSecretBackendMetadata.create(this.keyValueBackendProperties.getBackend(), context)); - } - - return result; - } - - return Collections.emptyList(); - } - - } - - private static class WrappedPropertySourceLocatorConfiguration implements PropertySourceLocatorConfiguration { - - private final List metadata; - - WrappedPropertySourceLocatorConfiguration(List metadata) { - this.metadata = metadata; - } - - @Override - public Collection getSecretBackends() { - return this.metadata; - } - - } - - private static class CompositePropertySourceConfiguration - implements PropertySourceLocatorConfiguration, EnvironmentAware { - - private final List configurations; - - CompositePropertySourceConfiguration(PropertySourceLocatorConfiguration... configurations) { - - List copy = new ArrayList<>(Arrays.asList(configurations)); - - AnnotationAwareOrderComparator.sortIfNecessary(copy); - - this.configurations = copy; - } - - @Override - public Collection getSecretBackends() { - - List result = new ArrayList<>(); - - for (PropertySourceLocatorConfiguration configuration : this.configurations) { - result.addAll(configuration.getSecretBackends()); - } - - return result; - } - - @Override - public void setEnvironment(Environment environment) { - - for (PropertySourceLocatorConfiguration configuration : this.configurations) { - if (configuration instanceof EnvironmentAware) { - ((EnvironmentAware) configuration).setEnvironment(environment); - } - } - } - - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveAutoConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveAutoConfiguration.java deleted file mode 100644 index 99ed128a..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveAutoConfiguration.java +++ /dev/null @@ -1,311 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import reactor.core.publisher.Flux; -import reactor.netty.http.client.HttpClient; - -import org.springframework.beans.factory.BeanFactory; -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.beans.factory.ListableBeanFactory; -import org.springframework.beans.factory.ObjectFactory; -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.context.ConfigurableApplicationContext; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.core.annotation.AnnotationAwareOrderComparator; -import org.springframework.http.client.reactive.ClientHttpConnector; -import org.springframework.lang.Nullable; -import org.springframework.util.Assert; -import org.springframework.vault.authentication.AuthenticationStepsFactory; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.ReactiveLifecycleAwareSessionManager; -import org.springframework.vault.authentication.ReactiveSessionManager; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.authentication.VaultTokenSupplier; -import org.springframework.vault.client.ReactiveVaultEndpointProvider; -import org.springframework.vault.client.SimpleVaultEndpointProvider; -import org.springframework.vault.client.VaultEndpointProvider; -import org.springframework.vault.client.WebClientBuilder; -import org.springframework.vault.client.WebClientCustomizer; -import org.springframework.vault.client.WebClientFactory; -import org.springframework.vault.core.ReactiveVaultOperations; -import org.springframework.vault.core.ReactiveVaultTemplate; -import org.springframework.vault.support.ClientOptions; -import org.springframework.vault.support.SslConfiguration; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.springframework.cloud.vault.config.VaultAutoConfiguration.TaskSchedulerWrapper; - -/** - * {@link EnableAutoConfiguration Auto-configuration} for reactive Spring Vault support. - *

- * This auto-configuration only supports static endpoints without - * {@link VaultEndpointProvider} support as endpoint providers could be potentially - * blocking implementations. - * - * @author Mark Paluch - * @since 3.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true) -@ConditionalOnExpression("${spring.cloud.vault.reactive.enabled:true}") -@ConditionalOnClass({ Flux.class, WebClient.class, ReactiveVaultOperations.class, HttpClient.class }) -@EnableConfigurationProperties({ VaultProperties.class }) -@AutoConfigureBefore(VaultAutoConfiguration.class) -public class VaultReactiveAutoConfiguration implements InitializingBean { - - @Nullable - private final ConfigurableApplicationContext applicationContext; - - private final VaultProperties vaultProperties; - - private final VaultReactiveConfiguration configuration; - - @Nullable - private final ReactiveVaultEndpointProvider reactiveEndpointProvider; - - @Nullable - private final VaultEndpointProvider endpointProvider; - - private final List customizers; - - /** - * @deprecated since 3.0.2, use - * {@link #VaultReactiveAutoConfiguration(ConfigurableApplicationContext, VaultProperties, ObjectProvider, ObjectProvider, ObjectProvider)} - * instead. - */ - @Deprecated - public VaultReactiveAutoConfiguration(VaultProperties vaultProperties, - ObjectProvider reactiveEndpointProvider, - ObjectProvider endpointProvider, - ObjectProvider> webClientCustomizers) { - this(null, vaultProperties, reactiveEndpointProvider, endpointProvider, webClientCustomizers); - } - - @Autowired - public VaultReactiveAutoConfiguration(@Nullable ConfigurableApplicationContext applicationContext, - VaultProperties vaultProperties, ObjectProvider reactiveEndpointProvider, - ObjectProvider endpointProvider, - ObjectProvider> webClientCustomizers) { - - this.applicationContext = applicationContext; - this.vaultProperties = vaultProperties; - this.configuration = new VaultReactiveConfiguration(vaultProperties); - - this.reactiveEndpointProvider = reactiveEndpointProvider.getIfAvailable(); - - if (this.reactiveEndpointProvider == null) { - this.endpointProvider = endpointProvider.getIfAvailable(() -> SimpleVaultEndpointProvider - .of(new VaultConfiguration(vaultProperties).createVaultEndpoint())); - } - else { - this.endpointProvider = null; - } - - this.customizers = new ArrayList<>(webClientCustomizers.getIfAvailable(Collections::emptyList)); - AnnotationAwareOrderComparator.sort(this.customizers); - } - - protected WebClientBuilder webClientBuilder(ClientHttpConnector connector) { - - if (this.reactiveEndpointProvider != null) { - return this.configuration.createWebClientBuilder(connector, this.reactiveEndpointProvider, - this.customizers); - } - - if (this.endpointProvider != null) { - return this.configuration.createWebClientBuilder(connector, this.endpointProvider, this.customizers); - } - - throw new IllegalStateException( - "Cannot create WebClientBuilder as neither ReactiveEndpointProvider nor EndpointProvider configured"); - } - - /** - * Creates a {@link ClientHttpConnectorWrapper} containing a - * {@link ClientHttpConnector}. {@link ClientHttpConnector} is not exposed as root - * bean because {@link ClientHttpConnector} is configured with {@link ClientOptions} - * and {@link SslConfiguration} which are not necessarily applicable for the whole - * application. - * @return the {@link ClientHttpConnectorWrapper} to wrap a - * {@link ClientHttpConnector} instance. - * @since 3.0.2 - */ - @Bean - @ConditionalOnMissingBean - public ClientHttpConnectorWrapper clientHttpConnectorWrapper() { - return new ClientHttpConnectorWrapper(createConnector(this.vaultProperties)); - } - - @Override - public void afterPropertiesSet() { - } - - /** - * Creates a {@link ClientHttpConnector} configured with {@link ClientOptions} and - * {@link SslConfiguration} which are not necessarily applicable for the whole - * application. - * @param vaultProperties the Vault properties. - * @return the {@link ClientHttpConnector}. - */ - protected ClientHttpConnector createConnector(VaultProperties vaultProperties) { - return new VaultReactiveConfiguration(vaultProperties).createClientHttpConnector(); - } - - /** - * Create a {@link WebClientFactory} bean that is used to produce {@link WebClient}. - * @return the {@link WebClientFactory}. - * @since 3.0 - */ - @Bean - @ConditionalOnMissingBean - public WebClientFactory vaultWebClientFactory() { - - ClientHttpConnector connector = getClientHttpConnector(); - - return new DefaultWebClientFactory(connector, this::webClientBuilder); - } - - protected ClientHttpConnector getClientHttpConnector() { - - if (this.applicationContext != null) { - return this.applicationContext.getBean(ClientHttpConnectorWrapper.class).getConnector(); - } - - return createConnector(this.vaultProperties); - } - - /** - * Creates a {@link ReactiveVaultTemplate}. - * @param sessionManager object provider for {@link ReactiveSessionManager}. - * @return the {@link ReactiveVaultTemplate} bean. - * @see #reactiveVaultSessionManager(BeanFactory, ObjectFactory, WebClientFactory) - */ - @Bean - @ConditionalOnMissingBean(ReactiveVaultOperations.class) - public ReactiveVaultTemplate reactiveVaultTemplate(ObjectProvider sessionManager) { - - WebClientBuilder webClientBuilder = webClientBuilder(getClientHttpConnector()); - - if (this.vaultProperties.getAuthentication() == VaultProperties.AuthenticationMethod.NONE) { - return new ReactiveVaultTemplate(webClientBuilder); - } - - return new ReactiveVaultTemplate(webClientBuilder, sessionManager.getObject()); - } - - /** - * @param beanFactory the {@link BeanFactory}. - * @param asyncTaskExecutorFactory the {@link ObjectFactory} for - * {@link TaskSchedulerWrapper}. - * @param webClientFactory the web client factory - * @return {@link ReactiveSessionManager} for reactive session use. - * @see ReactiveSessionManager - * @see ReactiveLifecycleAwareSessionManager - */ - @Bean - @ConditionalOnMissingBean - @ConditionalOnAuthentication - public ReactiveSessionManager reactiveVaultSessionManager(BeanFactory beanFactory, - ObjectFactory asyncTaskExecutorFactory, WebClientFactory webClientFactory) { - - VaultTokenSupplier vaultTokenSupplier = beanFactory.getBean("vaultTokenSupplier", VaultTokenSupplier.class); - - return this.configuration.createReactiveSessionManager(vaultTokenSupplier, - () -> asyncTaskExecutorFactory.getObject().getTaskScheduler(), webClientFactory); - } - - /** - * @param sessionManager the {@link ReactiveSessionManager}. - * @return {@link SessionManager} adapter wrapping {@link ReactiveSessionManager}. - */ - @Bean - @ConditionalOnMissingBean - @ConditionalOnAuthentication - public SessionManager vaultSessionManager(ReactiveSessionManager sessionManager) { - return this.configuration.createSessionManager(sessionManager); - } - - /** - * @param beanFactory the {@link BeanFactory}. - * @param webClientFactory the {@link WebClientFactory}. - * @return the {@link VaultTokenSupplier} for reactive Vault session management - * adapting {@link ClientAuthentication} that also implement - * {@link AuthenticationStepsFactory}. - * @see AuthenticationStepsFactory - */ - @Bean - @ConditionalOnMissingBean(name = "vaultTokenSupplier") - @ConditionalOnAuthentication - public VaultTokenSupplier vaultTokenSupplier(ListableBeanFactory beanFactory, WebClientFactory webClientFactory) { - - Assert.notNull(beanFactory, "BeanFactory must not be null"); - - return this.configuration.createVaultTokenSupplier(webClientFactory, - () -> beanFactory.getBeanProvider(AuthenticationStepsFactory.class, false).getIfAvailable(), - () -> beanFactory.getBeanProvider(ClientAuthentication.class, false).getIfAvailable()); - } - - /** - * Wrapper for {@link ClientHttpConnector} to not expose the bean globally. - * - * @since 3.0.2 - */ - public static class ClientHttpConnectorWrapper implements InitializingBean, DisposableBean { - - private final ClientHttpConnector connector; - - public ClientHttpConnectorWrapper(ClientHttpConnector connector) { - this.connector = connector; - } - - @Override - public void destroy() throws Exception { - if (this.connector instanceof DisposableBean) { - ((DisposableBean) this.connector).destroy(); - } - } - - @Override - public void afterPropertiesSet() throws Exception { - - if (this.connector instanceof InitializingBean) { - ((InitializingBean) this.connector).afterPropertiesSet(); - } - } - - public ClientHttpConnector getConnector() { - return this.connector; - } - - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveBootstrapConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveBootstrapConfiguration.java deleted file mode 100644 index b9fcdc3d..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveBootstrapConfiguration.java +++ /dev/null @@ -1,63 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.List; - -import reactor.core.publisher.Flux; -import reactor.netty.http.client.HttpClient; - -import org.springframework.beans.factory.ObjectProvider; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.cloud.bootstrap.BootstrapConfiguration; -import org.springframework.vault.client.ReactiveVaultEndpointProvider; -import org.springframework.vault.client.VaultEndpointProvider; -import org.springframework.vault.client.WebClientCustomizer; -import org.springframework.vault.core.ReactiveVaultOperations; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * {@link BootstrapConfiguration Bootstrap-configuration} for reactive Spring Vault - * support. - *

- * This auto-configuration only supports static endpoints without - * {@link org.springframework.vault.client.VaultEndpointProvider} support as endpoint - * providers could be potentially blocking implementations. - * - * @author Mark Paluch - * @since 2.0.0 - * @deprecated since 3.0, use {@link VaultReactiveAutoConfiguration} through - * {@code @EnableAutoConfiguration}. - */ -@Deprecated -@ConditionalOnProperty(name = "spring.cloud.vault.enabled", matchIfMissing = true) -@ConditionalOnExpression("${spring.cloud.vault.reactive.enabled:true}") -@ConditionalOnClass({ Flux.class, WebClient.class, ReactiveVaultOperations.class, HttpClient.class }) -@EnableConfigurationProperties({ VaultProperties.class }) -public class VaultReactiveBootstrapConfiguration extends VaultReactiveAutoConfiguration { - - public VaultReactiveBootstrapConfiguration(VaultProperties vaultProperties, - ObjectProvider reactiveEndpointProvider, - ObjectProvider endpointProvider, - ObjectProvider> webClientCustomizers) { - super(vaultProperties, reactiveEndpointProvider, endpointProvider, webClientCustomizers); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveConfiguration.java deleted file mode 100644 index 36e0a12e..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveConfiguration.java +++ /dev/null @@ -1,178 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.time.Duration; -import java.util.List; -import java.util.function.Supplier; - -import reactor.core.publisher.Mono; - -import org.springframework.http.client.reactive.ClientHttpConnector; -import org.springframework.scheduling.TaskScheduler; -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.vault.authentication.AuthenticationStepsFactory; -import org.springframework.vault.authentication.AuthenticationStepsOperator; -import org.springframework.vault.authentication.CachingVaultTokenSupplier; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.ReactiveLifecycleAwareSessionManager; -import org.springframework.vault.authentication.ReactiveSessionManager; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.authentication.TokenAuthentication; -import org.springframework.vault.authentication.VaultTokenSupplier; -import org.springframework.vault.client.ClientHttpConnectorFactory; -import org.springframework.vault.client.ReactiveVaultEndpointProvider; -import org.springframework.vault.client.VaultEndpointProvider; -import org.springframework.vault.client.VaultHttpHeaders; -import org.springframework.vault.client.WebClientBuilder; -import org.springframework.vault.client.WebClientCustomizer; -import org.springframework.vault.client.WebClientFactory; -import org.springframework.vault.support.ClientOptions; -import org.springframework.vault.support.SslConfiguration; -import org.springframework.vault.support.VaultToken; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * Support class for Vault configuration providing utility methods. - * - * @author Mark Paluch - * @since 3.0 - */ -final class VaultReactiveConfiguration { - - private final VaultProperties vaultProperties; - - VaultReactiveConfiguration(VaultProperties vaultProperties) { - this.vaultProperties = vaultProperties; - } - - ClientHttpConnector createClientHttpConnector() { - - ClientOptions clientOptions = new ClientOptions(Duration.ofMillis(this.vaultProperties.getConnectionTimeout()), - Duration.ofMillis(this.vaultProperties.getReadTimeout())); - - SslConfiguration sslConfiguration = VaultConfiguration.createSslConfiguration(this.vaultProperties.getSsl()); - - return ClientHttpConnectorFactory.create(clientOptions, sslConfiguration); - } - - WebClientBuilder createWebClientBuilder(ClientHttpConnector connector, - ReactiveVaultEndpointProvider endpointProvider, List customizers) { - - WebClientBuilder builder = WebClientBuilder.builder().httpConnector(connector) - .endpointProvider(endpointProvider); - - return applyCustomizer(customizers, builder); - } - - WebClientBuilder createWebClientBuilder(ClientHttpConnector connector, VaultEndpointProvider endpointProvider, - List customizers) { - - WebClientBuilder builder = WebClientBuilder.builder().httpConnector(connector) - .endpointProvider(endpointProvider); - - return applyCustomizer(customizers, builder); - } - - private WebClientBuilder applyCustomizer(List customizers, WebClientBuilder builder) { - customizers.forEach(builder::customizers); - - if (StringUtils.hasText(this.vaultProperties.getNamespace())) { - builder.defaultHeader(VaultHttpHeaders.VAULT_NAMESPACE, this.vaultProperties.getNamespace()); - } - - return builder; - } - - VaultTokenSupplier createVaultTokenSupplier(WebClientFactory webClientFactory, - Supplier stepsFactorySupplier, - Supplier clientAuthenticationSupplier) { - - AuthenticationStepsFactory authenticationStepsFactory = stepsFactorySupplier.get(); - if (authenticationStepsFactory != null) { - return createAuthenticationStepsOperator(authenticationStepsFactory, webClientFactory); - } - - ClientAuthentication clientAuthentication = clientAuthenticationSupplier.get(); - - if (clientAuthentication != null) { - - if (clientAuthentication instanceof TokenAuthentication) { - - TokenAuthentication authentication = (TokenAuthentication) clientAuthentication; - return () -> Mono.just(authentication.login()); - } - - if (clientAuthentication instanceof AuthenticationStepsFactory) { - return createAuthenticationStepsOperator((AuthenticationStepsFactory) clientAuthentication, - webClientFactory); - } - - throw new IllegalStateException(String.format("Cannot construct VaultTokenSupplier from %s. " - + "ClientAuthentication must implement AuthenticationStepsFactory or be TokenAuthentication", - clientAuthentication)); - } - - throw new IllegalStateException( - "Cannot construct VaultTokenSupplier. Please configure VaultTokenSupplier bean named vaultTokenSupplier."); - } - - private VaultTokenSupplier createAuthenticationStepsOperator(AuthenticationStepsFactory factory, - WebClientFactory webClientFactory) { - WebClient webClient = webClientFactory.create(); - return new AuthenticationStepsOperator(factory.getAuthenticationSteps(), webClient); - } - - SessionManager createSessionManager(ReactiveSessionManager sessionManager) { - return new ReactiveSessionManagerAdapter(sessionManager); - } - - ReactiveSessionManager createReactiveSessionManager(VaultTokenSupplier vaultTokenSupplier, - Supplier taskScheduler, WebClientFactory webClientFactory) { - - VaultProperties.SessionLifecycle lifecycle = this.vaultProperties.getSession().getLifecycle(); - - if (lifecycle.isEnabled()) { - WebClient webClient = webClientFactory.create(); - ReactiveLifecycleAwareSessionManager.RefreshTrigger trigger = new ReactiveLifecycleAwareSessionManager.FixedTimeoutRefreshTrigger( - lifecycle.getRefreshBeforeExpiry(), lifecycle.getExpiryThreshold()); - return new ReactiveLifecycleAwareSessionManager(vaultTokenSupplier, taskScheduler.get(), webClient, - trigger); - } - - return CachingVaultTokenSupplier.of(vaultTokenSupplier); - } - - private static final class ReactiveSessionManagerAdapter implements SessionManager { - - private final ReactiveSessionManager sessionManager; - - private ReactiveSessionManagerAdapter(ReactiveSessionManager sessionManager) { - this.sessionManager = sessionManager; - } - - @Override - public VaultToken getSessionToken() { - VaultToken token = this.sessionManager.getSessionToken().block(); - Assert.state(token != null, "ReactiveSessionManager returned a null VaultToken"); - return token; - } - - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveHealthIndicator.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveHealthIndicator.java deleted file mode 100644 index 646c2e38..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveHealthIndicator.java +++ /dev/null @@ -1,167 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.lang.reflect.UndeclaredThrowableException; -import java.util.Objects; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonProperty; -import com.fasterxml.jackson.databind.ObjectMapper; -import reactor.core.publisher.Mono; - -import org.springframework.boot.actuate.health.AbstractReactiveHealthIndicator; -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Health.Builder; -import org.springframework.lang.Nullable; -import org.springframework.vault.client.VaultHttpHeaders; -import org.springframework.vault.core.ReactiveVaultOperations; -import org.springframework.vault.support.VaultHealth; -import org.springframework.web.reactive.function.client.WebClientResponseException; - -/** - * Reactive health indicator reporting Vault's availability. - * - * @author Mark Paluch - * @since 2.0 - */ -public class VaultReactiveHealthIndicator extends AbstractReactiveHealthIndicator { - - private final ReactiveVaultOperations vaultOperations; - - public VaultReactiveHealthIndicator(ReactiveVaultOperations vaultOperations) { - this.vaultOperations = vaultOperations; - } - - @SuppressWarnings("BlockingMethodInNonBlockingContext") - private static Mono deserializeError(WebClientResponseException e) { - - try { - ObjectMapper mapper = new ObjectMapper(); - // Response is already materialized so not blocking here. - return Mono.just(mapper.readValue(e.getResponseBodyAsByteArray(), VaultHealthImpl.class)); - } - catch (Exception jsonError) { - UndeclaredThrowableException t = new UndeclaredThrowableException(jsonError); - t.addSuppressed(e); - return Mono.error(t); - } - } - - private static Health getHealth(Builder builder, VaultHealthImpl vaultHealthResponse) { - - HealthBuilderDelegate.contributeToHealth(vaultHealthResponse, builder); - return builder.build(); - } - - @Override - protected Mono doHealthCheck(Builder builder) { - - return this.vaultOperations - .doWithVault((it) -> it.get().uri("sys/health").header(VaultHttpHeaders.VAULT_NAMESPACE, "").exchange()) - .flatMap((it) -> it.bodyToMono(VaultHealthImpl.class)) - .onErrorResume(WebClientResponseException.class, VaultReactiveHealthIndicator::deserializeError) - .map((vaultHealthResponse) -> getHealth(builder, vaultHealthResponse)); - } - - @JsonIgnoreProperties(ignoreUnknown = true) - static class VaultHealthImpl implements VaultHealth { - - private final boolean initialized; - - private final boolean sealed; - - private final boolean standby; - - private final boolean performanceStandby; - - private final boolean replicationRecoverySecondary; - - private final int serverTimeUtc; - - @Nullable - private final String version; - - VaultHealthImpl(@JsonProperty("initialized") boolean initialized, @JsonProperty("sealed") boolean sealed, - @JsonProperty("standby") boolean standby, - @JsonProperty("performance_standby") boolean performanceStandby, - @Nullable @JsonProperty("replication_dr_mode") String replicationRecoverySecondary, - @JsonProperty("server_time_utc") int serverTimeUtc, @Nullable @JsonProperty("version") String version) { - - this.initialized = initialized; - this.sealed = sealed; - this.standby = standby; - this.performanceStandby = performanceStandby; - this.replicationRecoverySecondary = replicationRecoverySecondary != null - && !"disabled".equalsIgnoreCase(replicationRecoverySecondary); - this.serverTimeUtc = serverTimeUtc; - this.version = version; - } - - public boolean isInitialized() { - return this.initialized; - } - - public boolean isSealed() { - return this.sealed; - } - - public boolean isStandby() { - return this.standby; - } - - public boolean isPerformanceStandby() { - return this.performanceStandby; - } - - public boolean isRecoveryReplicationSecondary() { - return this.replicationRecoverySecondary; - } - - public int getServerTimeUtc() { - return this.serverTimeUtc; - } - - @Nullable - public String getVersion() { - return this.version; - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof VaultHealthImpl)) { - return false; - } - VaultHealthImpl that = (VaultHealthImpl) o; - return this.initialized == that.initialized && this.sealed == that.sealed && this.standby == that.standby - && this.performanceStandby == that.performanceStandby - && this.replicationRecoverySecondary == that.replicationRecoverySecondary - && this.serverTimeUtc == that.serverTimeUtc && Objects.equals(this.version, that.version); - } - - @Override - public int hashCode() { - return Objects.hash(this.initialized, this.sealed, this.standby, this.performanceStandby, - this.replicationRecoverySecondary, this.serverTimeUtc, this.version); - } - - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveHealthIndicatorConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveHealthIndicatorConfiguration.java deleted file mode 100644 index 53886003..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveHealthIndicatorConfiguration.java +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Map; - -import reactor.core.publisher.Flux; - -import org.springframework.boot.actuate.autoconfigure.health.CompositeReactiveHealthContributorConfiguration; -import org.springframework.boot.actuate.health.ReactiveHealthContributor; -import org.springframework.boot.autoconfigure.condition.ConditionalOnBean; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.vault.core.ReactiveVaultOperations; - -/** - * Configuration for {@link VaultReactiveHealthIndicator}. - * - * @author Mark Paluch - * @author Rastislav Zlacky - * @since 2.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass(Flux.class) -@ConditionalOnBean(ReactiveVaultOperations.class) -class VaultReactiveHealthIndicatorConfiguration - extends CompositeReactiveHealthContributorConfiguration { - - private final Map reactiveVaultTemplates; - - VaultReactiveHealthIndicatorConfiguration(Map reactiveVaultTemplates) { - super(VaultReactiveHealthIndicator::new); - this.reactiveVaultTemplates = reactiveVaultTemplates; - } - - @Bean(name = { "vaultHealthIndicator", "vaultReactiveHealthIndicator" }) - @ConditionalOnMissingBean(name = { "vaultHealthIndicator" }) - ReactiveHealthContributor vaultHealthIndicator() { - return createContributor(this.reactiveVaultTemplates); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveObservationAutoConfiguration.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveObservationAutoConfiguration.java deleted file mode 100644 index 5cae12da..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultReactiveObservationAutoConfiguration.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2016-2022 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import io.micrometer.observation.Observation; -import io.micrometer.observation.ObservationRegistry; -import reactor.core.publisher.Flux; - -import org.springframework.boot.actuate.metrics.web.reactive.client.ObservationWebClientCustomizer; -import org.springframework.boot.autoconfigure.AutoConfigureBefore; -import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; -import org.springframework.boot.autoconfigure.condition.ConditionalOnSingleCandidate; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.vault.client.WebClientCustomizer; -import org.springframework.web.reactive.function.client.DefaultClientRequestObservationConvention; -import org.springframework.web.reactive.function.client.WebClient; - -/** - * {@link org.springframework.boot.autoconfigure.EnableAutoConfiguration - * Auto-configuration} for Reactive Observability. - * - * @author Mark Paluch - * @since 3.0 - */ -@Configuration(proxyBeanMethods = false) -@ConditionalOnClass({ Observation.class, WebClient.class, Flux.class }) -@AutoConfigureBefore(VaultReactiveAutoConfiguration.class) -public class VaultReactiveObservationAutoConfiguration { - - @Bean - @ConditionalOnSingleCandidate(ObservationRegistry.class) - public WebClientCustomizer observationVaultWebClientCustomizer(ObservationRegistry observationRegistry) { - return webClientBuilder -> new ObservationWebClientCustomizer(observationRegistry, - new DefaultClientRequestObservationConvention()).customize(webClientBuilder); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultRuntimeHints.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultRuntimeHints.java deleted file mode 100644 index 7ea30695..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultRuntimeHints.java +++ /dev/null @@ -1,114 +0,0 @@ -/* - * Copyright 2018-2023 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.stream.Collectors; - -import org.springframework.aot.hint.MemberCategory; -import org.springframework.aot.hint.ReflectionHints; -import org.springframework.aot.hint.RuntimeHints; -import org.springframework.aot.hint.RuntimeHintsRegistrar; -import org.springframework.aot.hint.TypeReference; -import org.springframework.core.io.support.SpringFactoriesLoader; -import org.springframework.vault.authentication.LifecycleAwareSessionManager; -import org.springframework.vault.authentication.LifecycleAwareSessionManagerSupport; -import org.springframework.vault.authentication.ReactiveLifecycleAwareSessionManager; -import org.springframework.vault.authentication.SimpleSessionManager; -import org.springframework.vault.client.ClientHttpRequestFactoryFactory; -import org.springframework.vault.core.env.LeaseAwareVaultPropertySource; - -/** - * Runtime hints for Spring Cloud Vault usage with native images. - * - * @author Mark Paluch - */ -class VaultRuntimeHints implements RuntimeHintsRegistrar { - - @Override - public void registerHints(RuntimeHints hints, ClassLoader classLoader) { - - ReflectionHints reflection = hints.reflection(); - - // reflection required for ConfigDataLoader, early logging capture - reflection.registerTypes(Arrays.asList(SimpleSessionManager.class, LifecycleAwareSessionManager.class, - LifecycleAwareSessionManagerSupport.class, ClientHttpRequestFactoryFactory.class, - org.springframework.vault.core.env.VaultPropertySource.class, LeaseAwareVaultPropertySource.class) - .stream().map(TypeReference::of).collect(Collectors.toList()), - builder -> builder.withMembers(MemberCategory.DECLARED_FIELDS)); - - reflection.registerTypes( - Arrays.asList(VaultKeyValueBackendProperties.class).stream().map(TypeReference::of) - .collect(Collectors.toList()), - builder -> builder.withMembers(MemberCategory.DECLARED_FIELDS, - MemberCategory.INTROSPECT_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_METHODS, - MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS, MemberCategory.INVOKE_DECLARED_CONSTRUCTORS)); - - reflection.registerType( - TypeReference.of("org.springframework.vault.core.lease.SecretLeaseContainer$LeaseRenewalScheduler"), - builder -> builder.withMembers(MemberCategory.DECLARED_FIELDS)); - - reflection.registerType( - TypeReference.of("org.springframework.vault.core.lease.SecretLeaseEventPublisher$LoggingErrorListener"), - builder -> builder.withMembers(MemberCategory.DECLARED_FIELDS)); - - reflection.registerType(TypeReference - .of("org.springframework.cloud.vault.config.VaultReactiveConfiguration$ReactiveSessionManagerAdapter"), - builder -> builder.withMembers(MemberCategory.DECLARED_FIELDS)); - - if (VaultConfigDataLoader.webclientPresent && VaultConfigDataLoader.reactorPresent) { - reflection - .registerTypes( - Arrays.asList(ReactiveLifecycleAwareSessionManager.class).stream().map(TypeReference::of) - .collect(Collectors.toList()), - builder -> builder.withMembers(MemberCategory.DECLARED_FIELDS)); - } - - // presence checks - reflection.registerTypeIfPresent(classLoader, "reactor.core.publisher.Flux", MemberCategory.PUBLIC_CLASSES); - reflection.registerTypeIfPresent(classLoader, "org.springframework.web.reactive.function.client.WebClient", - MemberCategory.PUBLIC_CLASSES); - - reflection.registerTypeIfPresent(classLoader, "org.bouncycastle.crypto.signers.PSSSigner", - MemberCategory.PUBLIC_CLASSES); - reflection.registerTypeIfPresent(classLoader, "com.google.api.client.googleapis.auth.oauth2.GoogleCredential", - MemberCategory.PUBLIC_CLASSES); - reflection.registerTypeIfPresent(classLoader, "com.google.auth.oauth2.GoogleCredentials", - MemberCategory.PUBLIC_CLASSES); - - // reflection for pluggable config properties bindings - List pluggableDescriptors = new ArrayList<>(); - - pluggableDescriptors - .addAll(SpringFactoriesLoader.loadFactories(SecretBackendMetadataFactory.class, classLoader)); - pluggableDescriptors - .addAll(SpringFactoriesLoader.loadFactories(VaultSecretBackendDescriptor.class, classLoader)); - pluggableDescriptors - .addAll(SpringFactoriesLoader.loadFactories(VaultSecretBackendDescriptorFactory.class, classLoader)); - - List pluggableDescriptorReferences = pluggableDescriptors.stream().map(Object::getClass) - .map(TypeReference::of).collect(Collectors.toList()); - - reflection.registerTypes(pluggableDescriptorReferences, builder -> { - builder.withMembers(MemberCategory.INTROSPECT_DECLARED_CONSTRUCTORS, - MemberCategory.INTROSPECT_DECLARED_METHODS, MemberCategory.INVOKE_DECLARED_METHODS); - }); - } - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultSecretBackendDescriptor.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultSecretBackendDescriptor.java deleted file mode 100644 index 5dcb3994..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultSecretBackendDescriptor.java +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.boot.context.config.ConfigDataLocationResolver; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.cloud.bootstrap.BootstrapConfiguration; -import org.springframework.context.ApplicationContext; - -/** - * Interface to be implemented by objects that describe a Vault secret backend. Mainly for - * internal use within the framework. - * - *

- * Typically used by {@link SecretBackendMetadataFactory} to provide path and - * configuration to create a {@link SecretBackendMetadata} object. Instances are - * materialized through {@link Binder} and should be therefore annotated with - * {@link org.springframework.boot.context.properties.ConfigurationProperties @ConfigurationProperties}. - * Objects implementing this interface can be discovered either from the - * {@link ApplicationContext} when using {@link BootstrapConfiguration} (deprecated since - * 3.0) or {@code spring.factories} when using {@link ConfigDataLocationResolver}. - * - * @author Mark Paluch - * @see SecretBackendMetadataFactory - * @see SecretBackendMetadata - */ -public interface VaultSecretBackendDescriptor { - - /** - * Backend path without leading/trailing slashes. - * @return the backend path such as {@code secret} or {@code mysql}. - */ - String getBackend(); - - /** - * @return {@literal true} if the backend is enabled. - */ - boolean isEnabled(); - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultSecretBackendDescriptorFactory.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultSecretBackendDescriptorFactory.java deleted file mode 100644 index 2e2bdf7a..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultSecretBackendDescriptorFactory.java +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collection; - -/** - * Interface to be implemented by factory objects that produce - * {@link VaultSecretBackendDescriptor}. - * - * @author Mark Paluch - * @since 3.0.5 - */ -public interface VaultSecretBackendDescriptorFactory { - - /** - * Create a collection of {@link VaultSecretBackendDescriptor}s. - * @return a collection of {@link VaultSecretBackendDescriptor}s. - */ - Collection create(); - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultServiceInstanceProvider.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultServiceInstanceProvider.java deleted file mode 100644 index f8d3a9de..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/VaultServiceInstanceProvider.java +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.springframework.cloud.client.ServiceInstance; - -/** - * Provider interface to obtain a {@link ServiceInstance} to look up the Vault service. - * - * @author Mark Paluch - * @since 1.1 - */ -@FunctionalInterface -public interface VaultServiceInstanceProvider { - - /** - * Lookup {@link ServiceInstance} by {@code serviceId}. - * @param serviceId the service Id. - * @return {@link ServiceInstance} for the given {@code serviceId}. - * @throws IllegalStateException if no service with {@code serviceId} was found. - */ - ServiceInstance getVaultServerInstance(String serviceId); - -} diff --git a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/package-info.java b/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/package-info.java deleted file mode 100644 index 71e3982b..00000000 --- a/spring-cloud-vault-config/src/main/java/org/springframework/cloud/vault/config/package-info.java +++ /dev/null @@ -1,22 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/** - * Core Vault support classes. - */ -@org.springframework.lang.NonNullApi -@org.springframework.lang.NonNullFields -package org.springframework.cloud.vault.config; diff --git a/spring-cloud-vault-config/src/main/resources/META-INF/spring.factories b/spring-cloud-vault-config/src/main/resources/META-INF/spring.factories deleted file mode 100644 index cc383f7e..00000000 --- a/spring-cloud-vault-config/src/main/resources/META-INF/spring.factories +++ /dev/null @@ -1,14 +0,0 @@ -# Bootstrap Configuration -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.vault.config.DiscoveryClientVaultBootstrapConfiguration,\ -org.springframework.cloud.vault.config.ReactiveDiscoveryClientVaultBootstrapConfiguration,\ -org.springframework.cloud.vault.config.VaultBootstrapConfiguration,\ -org.springframework.cloud.vault.config.VaultReactiveBootstrapConfiguration,\ -org.springframework.cloud.vault.config.VaultBootstrapPropertySourceConfiguration -# ConfigData Resolver -org.springframework.boot.context.config.ConfigDataLocationResolver=\ -org.springframework.cloud.vault.config.VaultConfigDataLocationResolver -# ConfigData Loader -org.springframework.boot.context.config.ConfigDataLoader=\ -org.springframework.cloud.vault.config.VaultConfigDataLoader - diff --git a/spring-cloud-vault-config/src/main/resources/META-INF/spring/aot.factories b/spring-cloud-vault-config/src/main/resources/META-INF/spring/aot.factories deleted file mode 100644 index 6c6e410c..00000000 --- a/spring-cloud-vault-config/src/main/resources/META-INF/spring/aot.factories +++ /dev/null @@ -1 +0,0 @@ -org.springframework.aot.hint.RuntimeHintsRegistrar=org.springframework.cloud.vault.config.VaultRuntimeHints diff --git a/spring-cloud-vault-config/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports b/spring-cloud-vault-config/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports deleted file mode 100644 index 3ad8e268..00000000 --- a/spring-cloud-vault-config/src/main/resources/META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports +++ /dev/null @@ -1,5 +0,0 @@ -org.springframework.cloud.vault.config.VaultObservationAutoConfiguration -org.springframework.cloud.vault.config.VaultReactiveObservationAutoConfiguration -org.springframework.cloud.vault.config.VaultReactiveAutoConfiguration -org.springframework.cloud.vault.config.VaultAutoConfiguration -org.springframework.cloud.vault.config.VaultHealthIndicatorAutoConfiguration diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ApplicationFailFastTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ApplicationFailFastTests.java deleted file mode 100644 index 73e9dd08..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ApplicationFailFastTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.junit.Ignore; -import org.junit.Test; - -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.builder.SpringApplicationBuilder; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assert.fail; - -/** - * Tests for fail fast option. - * - * @author Mark Paluch - */ -@SpringBootApplication - -public class ApplicationFailFastTests { - - @Test - public void contextLoadsWithFailFastUsingLeasing() { - try { - new SpringApplicationBuilder().sources(ApplicationFailFastTests.class).run("--server.port=0", - "--spring.cloud.bootstrap.enabled=true", "--spring.cloud.vault.failFast=true", - "--spring.cloud.vault.config.lifecycle.enabled=true", "--spring.cloud.vault.port=9999"); - fail("failFast option did not produce an exception"); - } - catch (Exception e) { - assertThat(e.getMessage()).isNotEmpty(); - } - } - - @Test - public void contextLoadsWithFailFastWithoutLeasing() { - try { - new SpringApplicationBuilder().sources(ApplicationFailFastTests.class).run("--server.port=0", - "--spring.cloud.bootstrap.enabled=true", "--spring.cloud.vault.failFast=true", - "--spring.cloud.vault.config.lifecycle.enabled=false", - "--spring.cloud.vault.session.lifecycle.enabled=false", "--spring.cloud.vault.port=9999"); - fail("failFast option did not produce an exception"); - } - catch (Exception e) { - assertThat(e.getMessage()).isNotEmpty(); - } - } - - @Test - @Ignore("Fails because of method errors in Discovery health check") - public void contextLoadsWithoutFailFast() { - new SpringApplicationBuilder().sources(ApplicationFailFastTests.class).run("--server.port=0", - "--spring.cloud.bootstrap.enabled=true", "--spring.cloud.vault.failFast=false", - "--spring.cloud.vault.port=9999"); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ClientAuthenticationFactoryUnitTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ClientAuthenticationFactoryUnitTests.java deleted file mode 100644 index c80ece70..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ClientAuthenticationFactoryUnitTests.java +++ /dev/null @@ -1,258 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.io.IOException; -import java.nio.charset.StandardCharsets; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.nio.file.StandardOpenOption; - -import org.junit.Test; -import org.springframework.boot.system.SystemProperties; -import org.springframework.core.io.ClassPathResource; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.vault.authentication.AppRoleAuthenticationOptions; -import org.springframework.vault.authentication.AppRoleAuthenticationOptions.RoleId; -import org.springframework.vault.authentication.AppRoleAuthenticationOptions.SecretId; -import org.springframework.vault.authentication.AwsIamAuthentication; -import org.springframework.vault.authentication.AwsIamAuthenticationOptions; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.ClientCertificateAuthentication; -import org.springframework.vault.authentication.PcfAuthentication; -import org.springframework.vault.authentication.TokenAuthentication; -import org.springframework.vault.support.VaultToken; -import org.springframework.web.client.RestTemplate; - -import software.amazon.awssdk.core.SdkSystemSetting; -import software.amazon.awssdk.regions.Region; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalStateException; -import static org.assertj.core.api.Assertions.assertThatThrownBy; - -/** - * Unit tests for {@link ClientAuthenticationFactory}. - * - * @author Mark Paluch - * @author Quincy Conduff - */ -public class ClientAuthenticationFactoryUnitTests { - - @Test - public void shouldSupportAwsIam() { - - try { - System.setProperty(SdkSystemSetting.AWS_ACCESS_KEY_ID.property(), "foo"); - System.setProperty(SdkSystemSetting.AWS_SECRET_ACCESS_KEY.property(), "bar"); - - VaultProperties properties = new VaultProperties(); - properties.getAwsIam().setRegion(Region.AWS_GLOBAL.id()); - properties.getAwsIam().setRole("bar"); - - ClientAuthenticationFactory factory = new ClientAuthenticationFactory(properties, new RestTemplate(), - new RestTemplate()); - AwsIamAuthentication authentication = (AwsIamAuthentication) factory.awsIamAuthentication(properties); - AwsIamAuthenticationOptions options = (AwsIamAuthenticationOptions) ReflectionTestUtils - .getField(authentication, "options"); - - assertThat(options.getRegionProvider().getRegion()).isEqualTo(Region.AWS_GLOBAL); - } - finally { - System.getProperties().remove(SdkSystemSetting.AWS_ACCESS_KEY_ID.property()); - System.getProperties().remove(SdkSystemSetting.AWS_SECRET_ACCESS_KEY.property()); - } - } - - @Test - public void shouldSupportAppRoleRoleIdProvidedSecretIdProvided() { - - VaultProperties properties = new VaultProperties(); - properties.getAppRole().setRoleId("foo"); - properties.getAppRole().setSecretId("bar"); - - AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties); - - assertThat(options.getRoleId()).isInstanceOf(RoleId.provided("foo").getClass()); - assertThat(options.getSecretId()).isInstanceOf(SecretId.provided("bar").getClass()); - } - - @Test - public void shouldSupportAppRoleRoleIdProvidedSecretIdAbsent() { - - VaultProperties properties = new VaultProperties(); - properties.getAppRole().setRoleId("foo"); - - AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties); - - assertThat(options.getRoleId()).isInstanceOf(RoleId.provided("foo").getClass()); - assertThat(options.getSecretId()).isInstanceOf(SecretId.absent().getClass()); - } - - @Test - public void shouldSupportAppRoleRoleIdProvidedSecretIdPull() { - - VaultProperties properties = new VaultProperties(); - properties.setToken("token"); - properties.getAppRole().setRoleId("foo"); - properties.getAppRole().setRole("my-role"); - - AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties); - - assertThat(options.getAppRole()).isEqualTo("my-role"); - assertThat(options.getRoleId()).isInstanceOf(RoleId.provided("foo").getClass()); - assertThat(options.getSecretId()).isInstanceOf(SecretId.pull(VaultToken.of("token")).getClass()); - } - - @Test - public void shouldSupportAppRoleFullPull() { - - VaultProperties properties = new VaultProperties(); - properties.setToken("token"); - properties.getAppRole().setRole("my-role"); - - AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties); - - assertThat(options.getAppRole()).isEqualTo("my-role"); - assertThat(options.getRoleId()).isInstanceOf(RoleId.pull(VaultToken.of("token")).getClass()); - assertThat(options.getSecretId()).isInstanceOf(SecretId.pull(VaultToken.of("token")).getClass()); - } - - @Test - public void shouldSupportAppRoleFullWrapped() { - - VaultProperties properties = new VaultProperties(); - properties.setToken("token"); - - AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties); - - assertThat(options.getRoleId()).isInstanceOf(RoleId.wrapped(VaultToken.of("token")).getClass()); - assertThat(options.getSecretId()).isInstanceOf(SecretId.wrapped(VaultToken.of("token")).getClass()); - } - - @Test - public void shouldSupportAppRoleRoleIdWrappedSecretIdProvided() { - - VaultProperties properties = new VaultProperties(); - properties.setToken("token"); - properties.getAppRole().setSecretId("bar"); - - AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties); - - assertThat(options.getRoleId()).isInstanceOf(RoleId.wrapped(VaultToken.of("token")).getClass()); - assertThat(options.getSecretId()).isInstanceOf(SecretId.provided("bar").getClass()); - } - - @Test - public void shouldSupportAppRoleRoleIdProvidedSecretIdWrapped() { - - VaultProperties properties = new VaultProperties(); - properties.setToken("token"); - properties.getAppRole().setRoleId("foo"); - - AppRoleAuthenticationOptions options = ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties); - - assertThat(options.getRoleId()).isInstanceOf(RoleId.provided("foo").getClass()); - assertThat(options.getSecretId()).isInstanceOf(SecretId.wrapped(VaultToken.of("token")).getClass()); - } - - @Test - public void shouldRejectUnconfiguredRoleId() { - - VaultProperties properties = new VaultProperties(); - - assertThatThrownBy(() -> ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - public void shouldRejectUnconfiguredRoleIdIfRoleNameSet() { - - VaultProperties properties = new VaultProperties(); - properties.getAppRole().setRole("my-role"); - - assertThatThrownBy(() -> ClientAuthenticationFactory.getAppRoleAuthenticationOptions(properties)) - .isInstanceOf(IllegalArgumentException.class); - } - - @Test - public void shouldSupportPcfAuthentication() { - - VaultProperties properties = new VaultProperties(); - properties.setAuthentication(VaultProperties.AuthenticationMethod.PCF); - properties.getPcf().setRole("my-role"); - properties.getPcf().setInstanceKey(new ClassPathResource("bootstrap.yml")); - properties.getPcf().setInstanceCertificate(new ClassPathResource("bootstrap.yml")); - - ClientAuthentication clientAuthentication = new ClientAuthenticationFactory(properties, new RestTemplate(), - new RestTemplate()).createClientAuthentication(); - - assertThat(clientAuthentication).isInstanceOf(PcfAuthentication.class); - } - - @Test - public void shouldSupportSslCertificateAuthentication() { - - VaultProperties properties = new VaultProperties(); - properties.setAuthentication(VaultProperties.AuthenticationMethod.CERT); - properties.getSsl().setCertAuthPath("bert"); - - ClientAuthentication clientAuthentication = new ClientAuthenticationFactory(properties, new RestTemplate(), - new RestTemplate()).createClientAuthentication(); - - assertThat(clientAuthentication).isInstanceOf(ClientCertificateAuthentication.class); - } - - @Test - public void shouldSupportTokenFromFile() throws IOException { - - VaultProperties properties = new VaultProperties(); - properties.setAuthentication(VaultProperties.AuthenticationMethod.TOKEN); - - Path vaultTokenPath = Paths.get(SystemProperties.get("user.home"), ".vault-token"); - Files.write(vaultTokenPath, "hello".getBytes(StandardCharsets.UTF_8), StandardOpenOption.WRITE, - StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE); - try { - ClientAuthentication clientAuthentication = new ClientAuthenticationFactory(properties, new RestTemplate(), - new RestTemplate()).createClientAuthentication(); - - assertThat(clientAuthentication).isInstanceOf(TokenAuthentication.class); - VaultToken token = clientAuthentication.login(); - - assertThat(new String(token.toCharArray())).isEqualTo("hello"); - } - finally { - Files.deleteIfExists(vaultTokenPath); - } - } - - @Test - public void tokenAuthShouldFailIfTokenFileNotExistsAndTokenEmpty() throws IOException { - - VaultProperties properties = new VaultProperties(); - properties.setAuthentication(VaultProperties.AuthenticationMethod.TOKEN); - Path vaultTokenPath = Paths.get(SystemProperties.get("user.home"), ".vault-token"); - Files.deleteIfExists(vaultTokenPath); - - ClientAuthenticationFactory factory = new ClientAuthenticationFactory(properties, new RestTemplate(), - new RestTemplate()); - - assertThatIllegalStateException().isThrownBy(factory::createClientAuthentication); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/DiscoveryClientVaultBootstrapConfigurationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/DiscoveryClientVaultBootstrapConfigurationTests.java deleted file mode 100644 index c870d617..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/DiscoveryClientVaultBootstrapConfigurationTests.java +++ /dev/null @@ -1,182 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.net.URI; -import java.util.Collections; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.junit.Test; -import org.mockito.Mockito; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.DiscoveryClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.vault.client.VaultEndpoint; -import org.springframework.vault.client.VaultEndpointProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link DiscoveryClientVaultBootstrapConfiguration}. - * - * @author Mark Paluch - */ -public class DiscoveryClientVaultBootstrapConfigurationTests { - - private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(DiscoveryClientVaultBootstrapConfiguration.class, VaultBootstrapConfiguration.class)); - - @Test - public void shouldRegisterDefaultBeans() { - - this.contextRunner - .withUserConfiguration(DiscoveryConfiguration.class).withPropertyValues("spring.cloud.vault.token=foo", - "spring.cloud.vault.discovery.enabled=true", "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - assertThat(context.getBean(VaultServiceInstanceProvider.class)) - .isInstanceOf(DiscoveryClientVaultServiceInstanceProvider.class); - - VaultEndpointProvider endpointProvider = context.getBean(VaultEndpointProvider.class); - VaultEndpoint vaultEndpoint = endpointProvider.getVaultEndpoint(); - assertThat(vaultEndpoint.getPort()).isEqualTo(1234); - }); - } - - @Test - public void shouldNotRegisterBeansIfDiscoveryDisabled() { - - this.contextRunner - .withUserConfiguration(DiscoveryConfiguration.class).withPropertyValues("spring.cloud.vault.token=foo", - "spring.cloud.vault.discovery.enabled=false", "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - assertThat(context.getBeanNamesForType(VaultServiceInstanceProvider.class)).isEmpty(); - }); - } - - @Test - public void shouldNotRegisterBeansIfVaultDisabled() { - - this.contextRunner.withUserConfiguration(DiscoveryConfiguration.class) - .withPropertyValues("spring.cloud.vault.token=foo", "spring.cloud.vault.enabled=false", - "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - assertThat(context.getBeanNamesForType(VaultServiceInstanceProvider.class)).isEmpty(); - }); - - } - - @Configuration(proxyBeanMethods = false) - static class DiscoveryConfiguration { - - @Bean - DiscoveryClient discoveryClient() { - - DiscoveryClient mock = Mockito.mock(DiscoveryClient.class); - when(mock.getInstances(anyString())) - .thenReturn(Collections.singletonList(new SimpleServiceInstance(URI.create("https://foo:1234")))); - - return mock; - } - - } - - static class SimpleServiceInstance implements ServiceInstance { - - private URI uri; - - private String host; - - private int port; - - private boolean secure; - - private Map metadata = new LinkedHashMap<>(); - - private String serviceId; - - SimpleServiceInstance(URI uri) { - this.setUri(uri); - } - - void setUri(URI uri) { - this.uri = uri; - this.host = this.uri.getHost(); - this.port = this.uri.getPort(); - String scheme = this.uri.getScheme(); - if ("https".equals(scheme)) { - this.secure = true; - } - - } - - public URI getUri() { - return this.uri; - } - - public String getHost() { - return this.host; - } - - public int getPort() { - return this.port; - } - - public boolean isSecure() { - return this.secure; - } - - public Map getMetadata() { - return this.metadata; - } - - public String getServiceId() { - return this.serviceId; - } - - public void setHost(String host) { - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } - - public void setSecure(boolean secure) { - this.secure = secure; - } - - public void setMetadata(Map metadata) { - this.metadata = metadata; - } - - public void setServiceId(String serviceId) { - this.serviceId = serviceId; - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/KeyValueSecretBackendMetadataUnitTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/KeyValueSecretBackendMetadataUnitTests.java deleted file mode 100644 index 68ed66c0..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/KeyValueSecretBackendMetadataUnitTests.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link KeyValueSecretBackendMetadata}. - * - * @author Mark Paluch - */ -public class KeyValueSecretBackendMetadataUnitTests { - - VaultKeyValueBackendProperties properties = new VaultKeyValueBackendProperties(); - - @Test - public void shouldCreateDefaultContexts() { - - List contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties, Collections.emptyList()); - - assertThat(contexts).hasSize(1).contains("application"); - } - - @Test - public void shouldCreateDefaultForAppNameAndDefaultContext() { - - this.properties.setApplicationName("my-app"); - - List contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties, Collections.emptyList()); - - assertThat(contexts).hasSize(2).containsSequence("my-app", "application"); - } - - @Test - public void shouldCreateDefaultForAppNameAndDefaultContextWithProfiles() { - - this.properties.setApplicationName("my-app"); - - List contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties, - Arrays.asList("cloud", "local")); - - assertThat(contexts).hasSize(6).containsSequence("my-app/local", "my-app/cloud", "my-app", "application/local", - "application/cloud", "application"); - } - - @Test - public void shouldCreateAppNameContextIfDefaultIsDisabled() { - - this.properties.setApplicationName("my-app"); - this.properties.setDefaultContext(""); - - List contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties, Collections.emptyList()); - - assertThat(contexts).hasSize(1).containsSequence("my-app"); - } - - @Test - public void shouldCreateContextsForCommaSeparatedAppName() { - - this.properties.setApplicationName("foo,bar"); - - List contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties, Collections.emptyList()); - - assertThat(contexts).hasSize(3).containsSequence("bar", "foo", "application"); - } - - @Test - public void shouldCreateContextsWithProfile() { - - this.properties.setApplicationName("foo,bar"); - - List contexts = KeyValueSecretBackendMetadata.buildContexts(this.properties, - Arrays.asList("cloud", "local")); - - assertThat(contexts).hasSize(9).containsSequence("bar/local", "bar/cloud", "bar", "foo/local", "foo/cloud", - "foo", "application/local", "application/cloud", "application"); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/KeyValueSecretIntegrationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/KeyValueSecretIntegrationTests.java deleted file mode 100644 index 09f0035f..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/KeyValueSecretIntegrationTests.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link VaultConfigTemplate} using the key-value secret backend. - * - * @author Mark Paluch - */ -public class KeyValueSecretIntegrationTests extends IntegrationTestSupport { - - private VaultProperties vaultProperties = Settings.createVaultProperties(); - - private VaultConfigOperations configOperations; - - @Before - public void setUp() { - - this.vaultProperties.setFailFast(false); - prepare().getVaultOperations().write("secret/app-name", createData()); - - this.configOperations = new VaultConfigTemplate(prepare().getVaultOperations(), this.vaultProperties); - } - - @Test - public void shouldReturnSecretsCorrectly() { - - Map secretProperties = this.configOperations - .read(KeyValueSecretBackendMetadata.create("secret", "app-name")).getData(); - - assertThat(secretProperties).containsAllEntriesOf(createExpectedMap()); - } - - @Test - public void shouldReturnNullIfNotFound() { - - Secrets secrets = this.configOperations.read(KeyValueSecretBackendMetadata.create("secret", "missing")); - - assertThat(secrets).isNull(); - } - - private Map createData() { - - Map data = new HashMap<>(); - - data.put("string", "value"); - data.put("number", 1234); - data.put("boolean", true); - - return data; - } - - private Map createExpectedMap() { - - Map data = new HashMap<>(); - - data.put("string", "value"); - data.put("number", 1234); - data.put("boolean", true); - - return data; - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/LeasingVaultPropertySourceLocatorUnitTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/LeasingVaultPropertySourceLocatorUnitTests.java deleted file mode 100644 index 389d3459..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/LeasingVaultPropertySourceLocatorUnitTests.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.PropertySource; -import org.springframework.vault.core.lease.SecretLeaseContainer; -import org.springframework.vault.core.lease.domain.RequestedSecret; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.verify; - -/** - * Unit tests for {@link LeasingVaultPropertySourceLocator}. - * - * @author Mark Paluch - */ -@RunWith(MockitoJUnitRunner.class) -public class LeasingVaultPropertySourceLocatorUnitTests { - - private LeasingVaultPropertySourceLocator propertySourceLocator; - - @Mock - private ConfigurableEnvironment configurableEnvironment; - - @Mock - private SecretLeaseContainer secretLeaseContainer; - - private VaultKeyValueBackendProperties properties = new VaultKeyValueBackendProperties(); - - @Before - public void before() { - - this.propertySourceLocator = new LeasingVaultPropertySourceLocator(new VaultProperties(), - VaultPropertySourceLocatorSupport.createConfiguration(this.properties), this.secretLeaseContainer); - } - - @Test - public void getOrderShouldReturnConfiguredOrder() { - - VaultProperties vaultProperties = new VaultProperties(); - vaultProperties.getConfig().setOrder(10); - - this.propertySourceLocator = new LeasingVaultPropertySourceLocator(vaultProperties, - VaultPropertySourceLocatorSupport.createConfiguration(new VaultKeyValueBackendProperties()), - this.secretLeaseContainer); - - assertThat(this.propertySourceLocator.getOrder()).isEqualTo(10); - } - - @Test - public void shouldLocatePropertySources() { - - PropertySource propertySource = this.propertySourceLocator.locate(this.configurableEnvironment); - - assertThat(propertySource).isInstanceOf(CompositePropertySource.class); - - CompositePropertySource composite = (CompositePropertySource) propertySource; - assertThat(composite.getPropertySources()).hasSize(1); - verify(this.secretLeaseContainer).addRequestedSecret(RequestedSecret.rotating("secret/application")); - } - - @Test - public void shouldLocateLeaseAwareSources() { - - RequestedSecret rotating = RequestedSecret.rotating("secret/rotating"); - DefaultSecretBackendConfigurer configurer = new DefaultSecretBackendConfigurer(); - configurer.add(rotating); - configurer.add("database/mysql/creds/readonly"); - - this.propertySourceLocator = new LeasingVaultPropertySourceLocator(new VaultProperties(), configurer, - this.secretLeaseContainer); - - PropertySource propertySource = this.propertySourceLocator.locate(this.configurableEnvironment); - - assertThat(propertySource).isInstanceOf(CompositePropertySource.class); - - verify(this.secretLeaseContainer).addRequestedSecret(rotating); - verify(this.secretLeaseContainer) - .addRequestedSecret(RequestedSecret.renewable("database/mysql/creds/readonly")); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/PropertyNameTransformerUnitTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/PropertyNameTransformerUnitTests.java deleted file mode 100644 index 7885dabd..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/PropertyNameTransformerUnitTests.java +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.HashMap; -import java.util.Map; - -import org.junit.Test; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link PropertyNameTransformer}. - * - * @author Mark Paluch - */ -public class PropertyNameTransformerUnitTests { - - @Test - public void shouldTranslateProperties() { - - PropertyNameTransformer transformer = new PropertyNameTransformer(); - transformer.addKeyTransformation("old-key", "new-key"); - - Map map = new HashMap<>(); - map.put("old-key", "value"); - map.put("other-key", "other-value"); - - assertThat(transformer.transformProperties(map)).containsEntry("new-key", "value").containsEntry("other-key", - "other-value"); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ReactiveDiscoveryClientVaultBootstrapConfigurationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ReactiveDiscoveryClientVaultBootstrapConfigurationTests.java deleted file mode 100644 index cdd87245..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ReactiveDiscoveryClientVaultBootstrapConfigurationTests.java +++ /dev/null @@ -1,221 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.net.URI; -import java.util.LinkedHashMap; -import java.util.Map; - -import org.junit.Test; -import org.mockito.Mockito; -import reactor.core.publisher.Flux; -import reactor.test.StepVerifier; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.cloud.client.ServiceInstance; -import org.springframework.cloud.client.discovery.ReactiveDiscoveryClient; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.vault.client.ReactiveVaultEndpointProvider; -import org.springframework.vault.client.VaultEndpoint; -import org.springframework.vault.client.VaultEndpointProvider; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.anyString; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link ReactiveDiscoveryClientVaultBootstrapConfiguration}. - * - * @author Mark Paluch - */ -public class ReactiveDiscoveryClientVaultBootstrapConfigurationTests { - - private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration(AutoConfigurations - .of(ReactiveDiscoveryClientVaultBootstrapConfiguration.class, VaultBootstrapConfiguration.class)); - - @Test - public void shouldRegisterDefaultBeans() { - - this.contextRunner.withUserConfiguration(ReactiveDiscoveryConfiguration.class) - .withPropertyValues("spring.cloud.vault.token=foo", "spring.cloud.vault.discovery.enabled=true", - "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - assertThat(context).hasSingleBean(ReactiveVaultEndpointProvider.class); - - ReactiveVaultEndpointProvider endpointProvider = context - .getBean(ReactiveVaultEndpointProvider.class); - - endpointProvider.getVaultEndpoint().as(StepVerifier::create).assertNext(actual -> { - assertThat(actual.getPort()).isEqualTo(1234); - }).verifyComplete(); - }); - } - - @Test - public void shouldRegisterVaultEndpointAdapterBean() { - - this.contextRunner.withUserConfiguration(BridgedDiscoveryConfiguration.class) - .withPropertyValues("spring.cloud.vault.token=foo", "spring.cloud.vault.discovery.enabled=true", - "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - assertThat(context).hasSingleBean(ReactiveVaultEndpointProvider.class); - - ReactiveVaultEndpointProvider endpointProvider = context - .getBean(ReactiveVaultEndpointProvider.class); - - endpointProvider.getVaultEndpoint().as(StepVerifier::create).assertNext(actual -> { - assertThat(actual.getPort()).isEqualTo(1234); - }).verifyComplete(); - }); - } - - @Test - public void shouldNotRegisterBeansIfDiscoveryDisabled() { - - this.contextRunner.withUserConfiguration(ReactiveDiscoveryConfiguration.class) - .withPropertyValues("spring.cloud.vault.token=foo", "spring.cloud.vault.discovery.enabled=false", - "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - assertThat(context.getBeanNamesForType(ReactiveVaultEndpointProvider.class)).isEmpty(); - }); - } - - @Test - public void shouldNotRegisterBeansIfVaultDisabled() { - - this.contextRunner.withUserConfiguration(ReactiveDiscoveryConfiguration.class) - .withPropertyValues("spring.cloud.vault.token=foo", "spring.cloud.vault.enabled=false", - "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - assertThat(context.getBeanNamesForType(ReactiveVaultEndpointProvider.class)).isEmpty(); - }); - - } - - @Configuration(proxyBeanMethods = false) - static class ReactiveDiscoveryConfiguration { - - @Bean - ReactiveDiscoveryClient reactiveDiscoveryClient() { - - ReactiveDiscoveryClient mock = Mockito.mock(ReactiveDiscoveryClient.class); - when(mock.getInstances(anyString())) - .thenReturn(Flux.just(new SimpleServiceInstance(URI.create("https://foo:1234")))); - - return mock; - } - - } - - @Configuration(proxyBeanMethods = false) - static class BridgedDiscoveryConfiguration { - - @Bean - VaultEndpointProvider vaultEndpointProvider() { - - VaultEndpointProvider mock = Mockito.mock(VaultEndpointProvider.class); - VaultEndpoint vaultEndpoint = VaultEndpoint.create("foo", 1234); - - when(mock.getVaultEndpoint()).thenReturn(vaultEndpoint); - - return mock; - } - - } - - static class SimpleServiceInstance implements ServiceInstance { - - private URI uri; - - private String host; - - private int port; - - private boolean secure; - - private Map metadata = new LinkedHashMap<>(); - - private String serviceId; - - SimpleServiceInstance(URI uri) { - this.setUri(uri); - } - - void setUri(URI uri) { - this.uri = uri; - this.host = this.uri.getHost(); - this.port = this.uri.getPort(); - String scheme = this.uri.getScheme(); - if ("https".equals(scheme)) { - this.secure = true; - } - - } - - public URI getUri() { - return this.uri; - } - - public String getHost() { - return this.host; - } - - public int getPort() { - return this.port; - } - - public boolean isSecure() { - return this.secure; - } - - public Map getMetadata() { - return this.metadata; - } - - public String getServiceId() { - return this.serviceId; - } - - public void setHost(String host) { - this.host = host; - } - - public void setPort(int port) { - this.port = port; - } - - public void setSecure(boolean secure) { - this.secure = secure; - } - - public void setMetadata(Map metadata) { - this.metadata = metadata; - } - - public void setServiceId(String serviceId) { - this.serviceId = serviceId; - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ReactiveVaultBootstrapConfigurationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ReactiveVaultBootstrapConfigurationTests.java deleted file mode 100644 index 7932b296..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ReactiveVaultBootstrapConfigurationTests.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.junit.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.ReactiveSessionManager; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.authentication.VaultTokenSupplier; -import org.springframework.vault.core.ReactiveVaultTemplate; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link VaultReactiveBootstrapConfiguration}. - * - * @author Mark Paluch - */ -public class ReactiveVaultBootstrapConfigurationTests { - - private ApplicationContextRunner contextRunner = new ApplicationContextRunner().withConfiguration( - AutoConfigurations.of(VaultBootstrapConfiguration.class, VaultReactiveBootstrapConfiguration.class)); - - @Test - public void shouldConfigureWithoutAuthentication() { - - this.contextRunner.withPropertyValues("spring.cloud.vault.kv.enabled=false", - "spring.cloud.vault.authentication=NONE", "spring.cloud.bootstrap.enabled=true").run(context -> { - - assertThat(context).doesNotHaveBean(SessionManager.class); - assertThat(context).doesNotHaveBean(ClientAuthentication.class); - assertThat(context).doesNotHaveBean(VaultTokenSupplier.class); - assertThat(context).doesNotHaveBean(ReactiveSessionManager.class); - assertThat(context).hasSingleBean(ReactiveVaultTemplate.class); - }); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ReactiveVaultOperationsTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ReactiveVaultOperationsTests.java deleted file mode 100644 index 2a5dfaa9..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/ReactiveVaultOperationsTests.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import reactor.test.StepVerifier; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.ReactiveVaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test using config infrastructure with token authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = ReactiveVaultOperationsTests.TestApplication.class, - properties = { "spring.cloud.vault.host=foo", "spring.cloud.vault.uri=https://localhost:8200", - "spring.cloud.bootstrap.enabled=true" }) -public class ReactiveVaultOperationsTests { - - @Autowired - ReactiveVaultOperations reactiveOperations; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - Map object = new HashMap<>(); - object.put("vault.value", "foo"); - object.put("nested", Collections.singletonMap("key", "value")); - - vaultRule.prepare().getVaultOperations().write("secret/testVaultApp", object); - } - - @Test - public void shouldAccessVault() { - - StepVerifier.create(this.reactiveOperations.read("secret/testVaultApp")).consumeNextWith(actual -> { - assertThat(actual.getData()).containsEntry("vault.value", "foo"); - }).verifyComplete(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultBootstrapConfigurationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultBootstrapConfigurationTests.java deleted file mode 100644 index 989fc752..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultBootstrapConfigurationTests.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.time.Duration; - -import org.junit.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.authentication.SimpleSessionManager; -import org.springframework.vault.client.RestTemplateFactory; -import org.springframework.vault.core.VaultTemplate; -import org.springframework.vault.support.SslConfiguration; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link VaultBootstrapConfiguration}. - * - * @author Mark Paluch - */ -public class VaultBootstrapConfigurationTests { - - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(VaultBootstrapConfiguration.class)); - - @Test - public void shouldConfigureWithoutAuthentication() { - - this.contextRunner.withPropertyValues("spring.cloud.vault.kv.enabled=false", - "spring.cloud.vault.authentication=NONE", "spring.cloud.bootstrap.enabled=true").run(context -> { - - assertThat(context).doesNotHaveBean(SessionManager.class); - assertThat(context).doesNotHaveBean(ClientAuthentication.class); - assertThat(context).hasSingleBean(VaultTemplate.class); - assertThat(context).hasSingleBean(RestTemplateFactory.class); - }); - } - - @Test - public void shouldApplySslSettings() { - - this.contextRunner.withPropertyValues("spring.cloud.vault.kv.enabled=false", - "spring.cloud.vault.authentication=NONE", "spring.cloud.bootstrap.enabled=true", - "spring.cloud.vault.ssl.enabled-protocols=TLSv1.2,TLSv1.3", - "spring.cloud.vault.ssl.enabled-cipher-suites=one,two").run(context -> { - - VaultProperties properties = context.getBean(VaultProperties.class); - - SslConfiguration sslConfiguration = VaultConfiguration.createSslConfiguration(properties.getSsl()); - - assertThat(sslConfiguration.getEnabledProtocols()).containsExactly("TLSv1.2", "TLSv1.3"); - assertThat(sslConfiguration.getEnabledCipherSuites()).containsExactly("one", "two"); - }); - } - - @Test - public void shouldDisableSessionManagement() { - - this.contextRunner - .withPropertyValues("spring.cloud.vault.kv.enabled=false", "spring.cloud.vault.token=foo", - "spring.cloud.vault.session.lifecycle.enabled=false", "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - SessionManager bean = context.getBean(SessionManager.class); - assertThat(bean).isExactlyInstanceOf(SimpleSessionManager.class); - }); - } - - @Test - public void shouldConfigureSessionManagement() { - - this.contextRunner.withPropertyValues("spring.cloud.vault.kv.enabled=false", "spring.cloud.vault.token=foo", - "spring.cloud.vault.session.lifecycle.refresh-before-expiry=11s", - "spring.cloud.vault.session.lifecycle.expiry-threshold=12s", "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - SessionManager bean = context.getBean(SessionManager.class); - - Object refreshTrigger = ReflectionTestUtils.getField(bean, "refreshTrigger"); - - assertThat(refreshTrigger).hasFieldOrPropertyWithValue("duration", Duration.ofSeconds(11)) - .hasFieldOrPropertyWithValue("expiryThreshold", Duration.ofSeconds(12)); - }); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultBootstrapPropertySourceConfigurationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultBootstrapPropertySourceConfigurationTests.java deleted file mode 100644 index 1b7946f2..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultBootstrapPropertySourceConfigurationTests.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.time.Duration; - -import org.junit.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.context.properties.EnableConfigurationProperties; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.core.lease.LeaseEndpoints; -import org.springframework.vault.core.lease.SecretLeaseContainer; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; - -/** - * Unit tests for {@link VaultBootstrapPropertySourceConfiguration}. - * - * @author Mark Paluch - * @author Mårten Svantesson - */ -public class VaultBootstrapPropertySourceConfigurationTests { - - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(VaultBootstrapPropertySourceConfiguration.class)); - - @Test - public void shouldConfigureExpiryTimeouts() { - - this.contextRunner.withUserConfiguration(MockConfiguration.class).withAllowBeanDefinitionOverriding(true) - .withPropertyValues("spring.cloud.vault.kv.enabled=false", - "spring.cloud.vault.config.lifecycle.expiry-threshold=5m", - "spring.cloud.vault.config.lifecycle.min-renewal=6m", - "spring.cloud.vault.config.lifecycle.lease-endpoints=Leases", - "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - SecretLeaseContainer container = context.getBean(SecretLeaseContainer.class); - verify(container).setExpiryThreshold(Duration.ofMinutes(5)); - verify(container).setMinRenewal(Duration.ofMinutes(6)); - verify(container).setLeaseEndpoints(LeaseEndpoints.Leases); - }); - } - - @EnableConfigurationProperties(VaultProperties.class) - @Configuration(proxyBeanMethods = false) - private static class MockConfiguration { - - @Bean - VaultOperations vaultOperations() { - return mock(VaultOperations.class); - } - - @Bean - VaultBootstrapConfiguration.TaskSchedulerWrapper taskSchedulerWrapper() { - return new VaultBootstrapConfiguration.TaskSchedulerWrapper(mock(ThreadPoolTaskScheduler.class)); - } - - @Bean - SecretLeaseContainer secretLeaseContainer(VaultProperties properties) { - - SecretLeaseContainer mock = mock(SecretLeaseContainer.class); - VaultConfiguration.customizeContainer(properties.getConfig().getLifecycle(), mock); - - return mock; - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultBootstrapperIntegrationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultBootstrapperIntegrationTests.java deleted file mode 100644 index da7d9a4c..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultBootstrapperIntegrationTests.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.After; -import org.junit.Before; -import org.junit.Test; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link VaultBootstrapper}. - * - * @author Mark Paluch - */ -public class VaultBootstrapperIntegrationTests extends IntegrationTestSupport { - - private ConfigurableApplicationContext context; - - @Before - public void before() { - - this.vaultRule.prepare().getVaultOperations().write("secret/VaultBootstrapPropertySourceConfigurationTests", - Collections.singletonMap("default-key", "default")); - - this.vaultRule.prepare().getVaultOperations().write("secret/customized", - Collections.singletonMap("key", "customized")); - - SpringApplication application = new SpringApplication(Config.class); - application.setWebApplicationType(WebApplicationType.NONE); - application.addBootstrapRegistryInitializer( - VaultBootstrapper.fromConfigurer(configurer -> configurer.add("secret/customized"))); - - this.context = application.run("--spring.application.name=VaultBootstrapPropertySourceConfigurationTests", - "--spring.config.import=vault:", "--spring.cloud.vault.token=" + Settings.token().getToken()); - } - - @Test - public void shouldApplyConfigurer() { - - assertThat(this.context.getEnvironment().getProperty("default-key")).isNull(); - assertThat(this.context.getEnvironment().getProperty("key")).isEqualTo("customized"); - } - - @After - public void after() { - if (this.context != null) { - this.context.close(); - } - } - - @SpringBootConfiguration(proxyBeanMethods = false) - @EnableAutoConfiguration - private static class Config { - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigAppIdCustomMechanismTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigAppIdCustomMechanismTests.java deleted file mode 100644 index b8eeace7..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigAppIdCustomMechanismTests.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.TestRestTemplateFactory; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.authentication.AppIdAuthentication; -import org.springframework.vault.authentication.AppIdAuthenticationOptions; -import org.springframework.vault.authentication.AppIdUserIdMechanism; -import org.springframework.vault.authentication.ClientAuthentication; -import org.springframework.vault.core.VaultOperations; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = { VaultConfigAppIdCustomMechanismTests.TestApplication.class }, - properties = { "spring.cloud.vault.authentication=appid", - "VaultConfigAppIdCustomMechanismTests.custom.config=true", - "spring.cloud.vault.applicationName=VaultConfigAppIdCustomMechanismTests", - "spring.main.allow-bean-definition-overriding=true", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigAppIdCustomMechanismTests { - - @Value("${vault.value}") - String configValue; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - VaultProperties vaultProperties = Settings.createVaultProperties(); - vaultProperties.setAuthentication(VaultProperties.AuthenticationMethod.APPID); - - if (!vaultRule.prepare().hasAuth(vaultProperties.getAppId().getAppIdPath())) { - vaultRule.prepare().mountAuth(vaultProperties.getAppId().getAppIdPath()); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - String rules = "{ \"name\": \"testpolicy\",\n" // - + " \"path\": {\n" // - + " \"*\": { \"policy\": \"read\" }\n" // - + " }\n" // - + "}"; - - vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("rules", rules)); - - String appId = VaultConfigAppIdCustomMechanismTests.class.getSimpleName(); - - vaultOperations.write("secret/" + appId, Collections.singletonMap("vault.value", appId)); - - Map appIdData = new HashMap<>(); - appIdData.put("value", "testpolicy"); // policy - appIdData.put("display_name", "this is my test application"); - - vaultOperations.write(String.format("auth/app-id/map/app-id/%s", appId), appIdData); - - Map userIdData = new HashMap<>(); - userIdData.put("value", appId); // name of the app-id - userIdData.put("cidr_block", "0.0.0.0/0"); - - String userId = new StaticUserIdMechanism().createUserId(); - - vaultOperations.write(String.format("auth/app-id/map/user-id/%s", userId), userIdData); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo(getClass().getSimpleName()); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - - @Configuration(proxyBeanMethods = false) - public static class BootstrapConfiguration { - - @ConditionalOnProperty("VaultConfigAppIdCustomMechanismTests.custom.config") - @Bean - ClientAuthentication clientAuthentication() { - - RestTemplate restTemplate = TestRestTemplateFactory.create(Settings.createSslConfiguration()); - - return new AppIdAuthentication(AppIdAuthenticationOptions.builder() - .appId(VaultConfigAppIdCustomMechanismTests.class.getSimpleName()) - .userIdMechanism(new StaticUserIdMechanism()).build(), restTemplate); - } - - } - - public static class StaticUserIdMechanism implements AppIdUserIdMechanism { - - @Override - public String createUserId() { - return "static-string"; - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigAppIdTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigAppIdTests.java deleted file mode 100644 index 5c6fe23a..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigAppIdTests.java +++ /dev/null @@ -1,116 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.authentication.IpAddressUserId; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test using config infrastructure with AppId authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigAppIdTests.TestApplication.class, - properties = { "spring.cloud.vault.authentication=appid", "spring.cloud.vault.app-id.user-id=IP_ADDRESS", - "spring.cloud.vault.application-name=VaultConfigAppIdTests", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigAppIdTests { - - @Value("${vault.value}") - String configValue; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - VaultProperties vaultProperties = Settings.createVaultProperties(); - vaultProperties.setAuthentication(VaultProperties.AuthenticationMethod.APPID); - vaultProperties.getAppId().setUserId(VaultProperties.AppIdProperties.IP_ADDRESS); - - if (!vaultRule.prepare().hasAuth(vaultProperties.getAppId().getAppIdPath())) { - vaultRule.prepare().mountAuth(vaultProperties.getAppId().getAppIdPath()); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - String rules = "{ \"name\": \"testpolicy\",\n" // - + " \"path\": {\n" // - + " \"*\": { \"policy\": \"read\" }\n" // - + " }\n" // - + "}"; - - vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("rules", rules)); - - String appId = VaultConfigAppIdTests.class.getSimpleName(); - - vaultOperations.write("secret/" + VaultConfigAppIdTests.class.getSimpleName(), - Collections.singletonMap("vault.value", "foo")); - - Map appIdData = new HashMap<>(); - appIdData.put("value", "testpolicy"); // policy - appIdData.put("display_name", "this is my test application"); - - vaultOperations.write(String.format("auth/app-id/map/app-id/%s", appId), appIdData); - - Map userIdData = new HashMap<>(); - userIdData.put("value", appId); // name of the app-id - userIdData.put("cidr_block", "0.0.0.0/0"); - - String userId = new IpAddressUserId().createUserId(); - - vaultOperations.write(String.format("auth/app-id/map/user-id/%s", userId), userIdData); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo("foo"); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigAppRoleTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigAppRoleTests.java deleted file mode 100644 index 954e57d8..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigAppRoleTests.java +++ /dev/null @@ -1,122 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Integration test using config infrastructure with AppRole authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigAppRoleTests.TestApplication.class, - properties = { "spring.cloud.vault.authentication=approle", - "spring.cloud.vault.application-name=VaultConfigAppRoleTests", "spring.cloud.bootstrap.enabled=true" }) -// see -// https://github.com/spring-cloud/spring-cloud-commons/issues/214 -public class VaultConfigAppRoleTests { - - @Value("${vault.value}") - String configValue; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.1"))); - - VaultProperties vaultProperties = Settings.createVaultProperties(); - - if (!vaultRule.prepare().hasAuth(vaultProperties.getAppRole().getAppRolePath())) { - vaultRule.prepare().mountAuth(vaultProperties.getAppRole().getAppRolePath()); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - String rules = "{ \"name\": \"testpolicy\",\n" // - + " \"path\": {\n" // - + " \"*\": { \"policy\": \"read\" }\n" // - + " }\n" // - + "}"; - - vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("rules", rules)); - - String appId = VaultConfigAppRoleTests.class.getSimpleName(); - - vaultOperations.write("secret/" + VaultConfigAppRoleTests.class.getSimpleName(), - Collections.singletonMap("vault.value", "foo")); - - Map withSecretId = new HashMap<>(); - withSecretId.put("policies", "testpolicy"); // policy - withSecretId.put("bound_cidr_list", "0.0.0.0/0"); - withSecretId.put("bind_secret_id", "true"); - - vaultOperations.write("auth/approle/role/with-secret-id", withSecretId); - - String roleId = (String) vaultOperations.read("auth/approle/role/with-secret-id/role-id").getData() - .get("role_id"); - String secretId = (String) vaultOperations - .write(String.format("auth/approle/role/with-secret-id/secret-id", "with-secret-id"), null).getData() - .get("secret_id"); - - System.setProperty("spring.cloud.vault.app-role.role-id", roleId); - System.setProperty("spring.cloud.vault.app-role.secret-id", secretId); - - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo("foo"); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigCubbyholeAuthenticationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigCubbyholeAuthenticationTests.java deleted file mode 100644 index c34fc41a..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigCubbyholeAuthenticationTests.java +++ /dev/null @@ -1,105 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.support.VaultResponse; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Integration test using config infrastructure with Cubbyhole authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigCubbyholeAuthenticationTests.TestApplication.class, - properties = { "spring.cloud.vault.authentication=cubbyhole", - "spring.cloud.vault.kv.applicationName=VaultConfigCubbyholeAuthenticationTests", - "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigCubbyholeAuthenticationTests { - - @Value("${vault.value}") - String configValue; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.6.1"))); - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - vaultOperations.write("secret/" + VaultConfigCubbyholeAuthenticationTests.class.getSimpleName(), - Collections.singletonMap("vault.value", VaultConfigCubbyholeAuthenticationTests.class.getSimpleName())); - - VaultResponse vaultResponse = vaultOperations.doWithSession(restOperations -> { - - HttpHeaders headers = new HttpHeaders(); - headers.add("X-Vault-Wrap-TTL", "1h"); - - return restOperations.postForObject("/auth/token/create", new HttpEntity<>(headers), VaultResponse.class); - }); - - String initialToken = vaultResponse.getWrapInfo().get("token"); - System.setProperty("spring.cloud.vault.token", initialToken); - } - - @AfterClass - public static void afterClass() { - System.clearProperty("spring.cloud.vault.token"); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo(getClass().getSimpleName()); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLoaderIntegrationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLoaderIntegrationTests.java deleted file mode 100644 index 75f2596e..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLoaderIntegrationTests.java +++ /dev/null @@ -1,104 +0,0 @@ -/* - * Copyright 2020-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.boot.SpringApplication; -import org.springframework.boot.SpringBootConfiguration; -import org.springframework.boot.WebApplicationType; -import org.springframework.boot.autoconfigure.EnableAutoConfiguration; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.context.ConfigurableApplicationContext; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.fail; - -/** - * Integration tests for {@link VaultConfigDataLoader}. - * - * @author Mark Paluch - */ -public class VaultConfigDataLoaderIntegrationTests extends IntegrationTestSupport { - - @Before - public void before() { - - this.vaultRule.prepare().getVaultOperations().write("secret/my-config-loader", - Collections.singletonMap("default-key", "default")); - - this.vaultRule.prepare().getVaultOperations().write("secret/my-config-loader/cloud", - Collections.singletonMap("default-key", "cloud")); - } - - @Test - public void shouldConsiderProfiles() { - - SpringApplication application = new SpringApplication(Config.class); - application.setWebApplicationType(WebApplicationType.NONE); - application.setAdditionalProfiles("cloud"); - - try (ConfigurableApplicationContext context = application.run("--spring.application.name=my-config-loader", - "--spring.config.import=vault:", "--spring.cloud.vault.token=" + Settings.token().getToken())) { - - assertThat(context.getEnvironment().getProperty("default-key")).isEqualTo("cloud"); - } - } - - @Test - public void vaultLocationEndingWithSlashShouldFail() { - - SpringApplication application = new SpringApplication(Config.class); - application.setWebApplicationType(WebApplicationType.NONE); - application.setAdditionalProfiles("cloud"); - - try (ConfigurableApplicationContext context = application.run("--spring.application.name=my-config-loader", - "--spring.config.import=vault://secret/my-config-loader/cloud/", - "--spring.cloud.vault.token=" + Settings.token().getToken())) { - - fail("expected exception"); - } - catch (IllegalArgumentException e) { - assertThat(e).hasMessageContaining( - "Location 'vault://secret/my-config-loader/cloud/' must not end with a trailing slash"); - } - } - - @Test - public void shouldConsiderDisabledVault() { - - SpringApplication application = new SpringApplication(Config.class); - application.setWebApplicationType(WebApplicationType.NONE); - - try (ConfigurableApplicationContext context = application.run("--spring.application.name=my-config-loader", - "--spring.config.import=optional:vault:", "--spring.cloud.vault.enabled=false")) { - - assertThat(context.getEnvironment().getProperty("default-key")).isNull(); - } - } - - @SpringBootConfiguration(proxyBeanMethods = false) - @EnableAutoConfiguration - private static class Config { - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLoaderUnitTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLoaderUnitTests.java deleted file mode 100644 index aad54435..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLoaderUnitTests.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright 2020-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.junit.Test; - -import org.springframework.boot.DefaultBootstrapContext; -import org.springframework.boot.context.config.ConfigData; -import org.springframework.boot.logging.DeferredLogs; -import org.springframework.cloud.vault.util.IntegrationTestSupport; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link VaultConfigDataLoader}. - * - * @author Mark Paluch - */ -public class VaultConfigDataLoaderUnitTests extends IntegrationTestSupport { - - @Test - public void shouldConsiderDisabledVault() { - - VaultConfigDataLoader loader = new VaultConfigDataLoader(new DeferredLogs()); - DefaultBootstrapContext context = new DefaultBootstrapContext(); - - VaultProperties properties = new VaultProperties(); - properties.setEnabled(false); - - context.register(VaultProperties.class, it -> properties); - - ConfigData vaultDisabled = loader.load(() -> context, new VaultConfigLocation("foo", true)); - - assertThat(vaultDisabled).isNull(); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolverUnitTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolverUnitTests.java deleted file mode 100644 index b48917d8..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDataLocationResolverUnitTests.java +++ /dev/null @@ -1,140 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import org.junit.Before; -import org.junit.Test; -import org.springframework.boot.DefaultBootstrapContext; -import org.springframework.boot.context.config.ConfigDataLocation; -import org.springframework.boot.context.config.ConfigDataLocationResolverContext; -import org.springframework.boot.context.config.Profiles; -import org.springframework.boot.context.properties.bind.Binder; -import org.springframework.boot.context.properties.source.ConfigurationPropertySource; -import org.springframework.core.env.MapPropertySource; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatIllegalArgumentException; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * Unit tests for {@link VaultConfigDataLocationResolver}. - * - * @author Mark Paluch - * @author Jeffrey van der Laan - * @author Benjamin Bargeton - */ -public class VaultConfigDataLocationResolverUnitTests { - - ConfigDataLocationResolverContext contextMock = mock(ConfigDataLocationResolverContext.class); - - Profiles profilesMock = mock(Profiles.class); - - DefaultBootstrapContext bootstrapContext = new DefaultBootstrapContext(); - - @Before - public void before() { - when(this.contextMock.getBootstrapContext()).thenReturn(this.bootstrapContext); - when(this.contextMock.getBinder()).thenReturn(new Binder()); - } - - @Test - public void shouldDiscoverDefaultLocations() { - - VaultConfigDataLocationResolver resolver = new VaultConfigDataLocationResolver(); - - when(this.profilesMock.getActive()).thenReturn(Arrays.asList("a", "b")); - - assertThat( - resolver.resolveProfileSpecific(this.contextMock, ConfigDataLocation.of("vault:"), this.profilesMock)) - .hasSize(3); - - assertThat( - resolver.resolveProfileSpecific(this.contextMock, ConfigDataLocation.of("vault://"), this.profilesMock)) - .hasSize(3); - } - - @Test - public void shouldRejectLocationWithTrailingSlash() { - - VaultConfigDataLocationResolver resolver = new VaultConfigDataLocationResolver(); - - assertThatIllegalArgumentException() - .isThrownBy(() -> resolver.resolveProfileSpecific(this.contextMock, - ConfigDataLocation.of("vault://foo/"), this.profilesMock)) - .withMessage("Location 'vault://foo/' must not end with a trailing slash"); - } - - @Test - public void shouldDiscoverContextualLocations() { - - VaultConfigDataLocationResolver resolver = new VaultConfigDataLocationResolver(); - - List locations = resolver.resolveProfileSpecific(this.contextMock, - ConfigDataLocation.of("vault://my/context/path"), this.profilesMock); - - assertThat(locations).hasSize(1); - assertThat(locations.get(0)).hasToString("VaultConfigLocation [path='my/context/path', optional=false]"); - assertThat(locations.get(0).getSecretBackendMetadata().getPropertyTransformer() - .transformProperties(Collections.singletonMap("key", "value"))).containsEntry("key", "value"); - } - - @Test - public void shouldDiscoverContextualLocationsWithPrefix() { - - VaultConfigDataLocationResolver resolver = new VaultConfigDataLocationResolver(); - - List locations = resolver.resolveProfileSpecific(this.contextMock, - ConfigDataLocation.of("vault://my/context/path?prefix=myPrefix."), this.profilesMock); - - assertThat(locations).hasSize(1); - assertThat(locations.get(0).getSecretBackendMetadata().getPropertyTransformer() - .transformProperties(Collections.singletonMap("key", "value"))).containsEntry("myPrefix.key", "value"); - } - - @Test - public void shouldNotPrefixWhenPrefixIsEmpty() { - - VaultConfigDataLocationResolver resolver = new VaultConfigDataLocationResolver(); - - List locations = resolver.resolveProfileSpecific(this.contextMock, - ConfigDataLocation.of("vault://my/context/path?prefix="), this.profilesMock); - - assertThat(locations).hasSize(1); - assertThat(locations.get(0).getSecretBackendMetadata().getPropertyTransformer() - .transformProperties(Collections.singletonMap("key", "value"))).containsEntry("key", "value"); - } - - @Test - public void kvProfilesPropertyPrecedenceShouldBeRespected() { - - VaultConfigDataLocationResolver resolver = new VaultConfigDataLocationResolver(); - - when(this.profilesMock.getActive()).thenReturn(Arrays.asList("a", "b")); - when(this.contextMock.getBinder()).thenReturn(new Binder(ConfigurationPropertySource.from( - new MapPropertySource("test", Collections.singletonMap("spring.cloud.vault.kv.profiles", "c, d, e"))))); - - assertThat( - resolver.resolveProfileSpecific(this.contextMock, ConfigDataLocation.of("vault://"), this.profilesMock)) - .hasSize(4); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDisabledTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDisabledTests.java deleted file mode 100644 index 3ab01094..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigDisabledTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.context.ApplicationContext; -import org.springframework.core.env.Environment; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultTemplate; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test using config infrastructure with token authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigDisabledTests.TestApplication.class, - properties = { "spring.cloud.vault.enabled=false", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigDisabledTests { - - @Autowired - Environment environment; - - @Autowired - ApplicationContext applicationContext; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - vaultRule.prepare().getVaultOperations().write("secret/testVaultApp", - Collections.singletonMap("vault.value", "foo")); - } - - @Test - public void shouldNotContainVaultProperties() { - assertThat(this.environment.containsProperty("vault.value")).isFalse(); - } - - @Test - public void shouldNotContainVaultBeans() { - - // Beans are registered in parent (bootstrap) context. - ApplicationContext parent = this.applicationContext.getParent(); - - assertThat(parent.getBeanNamesForType(VaultTemplate.class)).isEmpty(); - assertThat(parent.getBeanNamesForType(VaultPropertySourceLocator.class)).isEmpty(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigKeyValueBackendDisabledTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigKeyValueBackendDisabledTests.java deleted file mode 100644 index 0988cf56..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigKeyValueBackendDisabledTests.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.core.env.Environment; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test using config infrastructure with token authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigKeyValueBackendDisabledTests.TestApplication.class, - properties = "spring.cloud.vault.kv.enabled=false") -public class VaultConfigKeyValueBackendDisabledTests { - - @Autowired - Environment environment; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - vaultRule.prepare().getVaultOperations().write("secret/testVaultApp", - Collections.singletonMap("vault.value", "foo")); - } - - @Test - public void shouldNotContainVaultProperties() { - assertThat(this.environment.containsProperty("vault.value")).isFalse(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigKubernetesTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigKubernetesTests.java deleted file mode 100644 index 5cdc0eaa..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigKubernetesTests.java +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.assertj.core.util.Files; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.util.StringUtils; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.support.Policy; -import org.springframework.vault.support.Policy.BuiltinCapabilities; -import org.springframework.vault.support.Policy.Rule; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; -import static org.springframework.cloud.vault.util.Settings.findWorkDir; - -/** - * Integration test using config infrastructure with Kubernetes authentication. - * - * @author Michal Budzyn - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigKubernetesTests.TestApplication.class, - properties = { "spring.cloud.vault.authentication=kubernetes", "spring.cloud.vault.kubernetes.role=my-role", - "spring.cloud.vault.kubernetes.service-account-token-file=../work/minikube/hello-minikube-token", - "spring.cloud.vault.application-name=VaultConfigKubernetesTests", - "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigKubernetesTests { - - @Value("${vault.value}") - String configValue; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - String minikubeIp = System.getProperty("MINIKUBE_IP"); - assumeTrue(StringUtils.hasText(minikubeIp) - && vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.8.3"))); - - if (!vaultRule.prepare().hasAuth("kubernetes")) { - vaultRule.prepare().mountAuth("kubernetes"); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - Policy policy = Policy.of(Rule.builder().path("*").capabilities(BuiltinCapabilities.READ).build()); - - vaultOperations.opsForSys().createOrUpdatePolicy("testpolicy", policy); - - vaultOperations.write("secret/" + VaultConfigKubernetesTests.class.getSimpleName(), - Collections.singletonMap("vault.value", "foo")); - - File workDir = findWorkDir(); - String certificate = Files.contentOf(new File(workDir, "minikube/ca.crt"), StandardCharsets.US_ASCII); - - String host = String.format("https://%s:8443", minikubeIp); - Map kubeConfig = new HashMap<>(); - kubeConfig.put("kubernetes_ca_cert", certificate); - kubeConfig.put("kubernetes_host", host); - vaultOperations.write("auth/kubernetes/config", kubeConfig); - - Map roleData = new HashMap<>(); - roleData.put("bound_service_account_names", "default"); - roleData.put("bound_service_account_namespaces", "default"); - roleData.put("policies", "testpolicy"); - roleData.put("ttl", "1h"); - vaultOperations.write("auth/kubernetes/role/my-role", roleData); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo("foo"); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigLoaderSingleLocationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigLoaderSingleLocationTests.java deleted file mode 100644 index 15f4ad65..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigLoaderSingleLocationTests.java +++ /dev/null @@ -1,89 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.context.ApplicationContext; -import org.springframework.core.env.Environment; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test using Spring Boot's ConfigData API with token authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigLoaderSingleLocationTests.TestApplication.class, properties = { - "spring.cloud.vault.uri=https://localhost:8200", "spring.config.import=vault:secret/config-location" }) -public class VaultConfigLoaderSingleLocationTests { - - @Autowired - Environment environment; - - @Autowired - ApplicationContext applicationContext; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - Map object = new HashMap<>(); - object.put("vault-key", "config-data works"); - object.put("nested", Collections.singletonMap("key", "value")); - - vaultRule.prepare().getVaultOperations().write("secret/config-location", object); - } - - @Test - public void shouldContainProperty() { - - assertThat(this.environment.containsProperty("vault-key")).isTrue(); - assertThat(this.environment.getProperty("vault-key")).isEqualTo("config-data works"); - } - - @SpringBootApplication(exclude = RefreshAutoConfiguration.class) - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigLoaderTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigLoaderTests.java deleted file mode 100644 index 3db3497d..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigLoaderTests.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.autoconfigure.RefreshAutoConfiguration; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.context.ApplicationContext; -import org.springframework.core.env.Environment; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultTemplate; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test using Spring Boot's ConfigData API with token authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigLoaderTests.TestApplication.class, - properties = { "spring.cloud.vault.uri=https://localhost:8200", - "spring.cloud.vault.application-name=config-data", "spring.config.import=vault:" }) -public class VaultConfigLoaderTests { - - @Value("${vault.value}") - String configValue; - - @Autowired - Environment environment; - - @Autowired - ApplicationContext applicationContext; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - Map object = new HashMap<>(); - object.put("vault.value", "config-data works"); - object.put("nested", Collections.singletonMap("key", "value")); - - vaultRule.prepare().getVaultOperations().write("secret/config-data", object); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo("config-data works"); - } - - @Test - public void shouldContainProperty() { - - assertThat(this.environment.containsProperty("vault.value")).isTrue(); - assertThat(this.environment.getProperty("vault.value")).isEqualTo("config-data works"); - - assertThat(this.environment.containsProperty("nested.key")).isTrue(); - assertThat(this.environment.getProperty("nested.key")).isEqualTo("value"); - } - - @Test - public void shouldContainVaultBeans() { - - assertThat(this.applicationContext.getBeanNamesForType(VaultTemplate.class)).isNotEmpty(); - } - - @Test - public void shouldNotRegisterPropertySourceLocator() { - - assertThat(this.applicationContext.getBeanNamesForType(LeasingVaultPropertySourceLocator.class)).isEmpty(); - } - - @Test - public void shouldNotContainRestTemplateArtifacts() { - - assertThat(this.applicationContext.getBeanNamesForType(RestTemplate.class)).isEmpty(); - assertThat(this.applicationContext.getBeanNamesForType(ClientHttpRequestFactory.class)).isEmpty(); - } - - @SpringBootApplication(exclude = RefreshAutoConfiguration.class) - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTemplateIntegrationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTemplateIntegrationTests.java deleted file mode 100644 index a808d22f..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTemplateIntegrationTests.java +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.Version; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests for {@link VaultConfigTemplate}. - * - * @author Mark Paluch - */ -public class VaultConfigTemplateIntegrationTests extends IntegrationTestSupport { - - @Before - public void before() { - prepare().getVaultOperations().write("secret/myapp", Collections.singletonMap("key", "value")); - } - - @Test - public void shouldReadValue() { - - VaultProperties vaultProperties = Settings.createVaultProperties(); - - VaultConfigTemplate template = new VaultConfigTemplate(prepare().getVaultOperations(), vaultProperties); - - Secrets secrets = template.read(KeyValueSecretBackendMetadata.create("secret", "myapp")); - - assertThat(secrets.getData()).containsEntry("key", "value"); - } - - @Test - public void shouldReadVersionedValue() { - - assumeTrue(this.vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.10.0"))); - - this.vaultRule.prepare().getVaultOperations().write("versioned/data/testVaultApp", - Collections.singletonMap("data", Collections.singletonMap("key", "value"))); - - VaultProperties vaultProperties = Settings.createVaultProperties(); - - VaultConfigTemplate template = new VaultConfigTemplate(prepare().getVaultOperations(), vaultProperties); - - Secrets secrets = template.read(KeyValueSecretBackendMetadata.create("versioned", "testVaultApp")); - - assertThat(secrets.getData()).containsEntry("key", "value"); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTests.java deleted file mode 100644 index 6fbdc032..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTests.java +++ /dev/null @@ -1,125 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.context.ApplicationContext; -import org.springframework.core.env.Environment; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultTemplate; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test using config infrastructure with token authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigTests.TestApplication.class, - properties = { "spring.cloud.vault.host=foo", "spring.cloud.vault.port=80", - "spring.cloud.vault.uri=https://localhost:8200", "spring.cloud.vault.application-name=testVaultApp", - "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigTests { - - @Value("${vault.value}") - String configValue; - - @Autowired - Environment environment; - - @Autowired - ApplicationContext applicationContext; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - Map object = new HashMap<>(); - object.put("vault.value", "foo"); - object.put("nested", Collections.singletonMap("key", "value")); - - vaultRule.prepare().getVaultOperations().write("secret/testVaultApp", object); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo("foo"); - } - - @Test - public void shouldContainProperty() { - - assertThat(this.environment.containsProperty("vault.value")).isTrue(); - assertThat(this.environment.getProperty("vault.value")).isEqualTo("foo"); - - assertThat(this.environment.containsProperty("nested.key")).isTrue(); - assertThat(this.environment.getProperty("nested.key")).isEqualTo("value"); - } - - @Test - public void shouldContainVaultBeans() { - - // Beans are registered in parent (bootstrap) context. - ApplicationContext parent = this.applicationContext.getParent(); - - assertThat(parent.getBeanNamesForType(VaultTemplate.class)).isNotEmpty(); - assertThat(parent.getBeanNamesForType(LeasingVaultPropertySourceLocator.class)).isNotEmpty(); - } - - @Test - public void shouldNotContainRestTemplateArtifacts() { - - // Beans are registered in parent (bootstrap) context. - ApplicationContext parent = this.applicationContext.getParent(); - - assertThat(parent.getBeanNamesForType(RestTemplate.class)).isEmpty(); - assertThat(parent.getBeanNamesForType(ClientHttpRequestFactory.class)).isEmpty(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTlsCertAuthenticationMountPathTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTlsCertAuthenticationMountPathTests.java deleted file mode 100644 index 7671416f..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTlsCertAuthenticationMountPathTests.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.assertj.core.util.Files; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.support.VaultMount; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.vault.util.Settings.findWorkDir; - -/** - * Integration test using config infrastructure with TLS certificate authentication. In - * case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Quincy Conduff - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigTlsCertAuthenticationMountPathTests.TestApplication.class, properties = { - "spring.cloud.vault.authentication=CERT", "spring.cloud.vault.ssl.key-store=file:../work/client-cert.jks", - "spring.cloud.vault.ssl.key-store-password=changeit", "spring.cloud.vault.ssl.cert-auth-path=nonstandard", - "spring.cloud.vault.application-name=VaultConfigTlsCertAuthenticationMountPathTests", - "spring.cloud.vault.reactive.enabled=false", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigTlsCertAuthenticationMountPathTests { - - @Value("${vault.value}") - String configValue; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - VaultProperties vaultProperties = Settings.createVaultProperties(); - - vaultProperties.getSsl().setCertAuthPath("nonstandard"); - - if (!vaultRule.prepare().hasAuth(vaultProperties.getSsl().getCertAuthPath())) { - vaultRule.prepare().getVaultOperations().opsForSys().authMount(vaultProperties.getSsl().getCertAuthPath(), - VaultMount.builder().type("cert").build()); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - String rules = "path \"*\" {\n capabilities = [\"read\"]\n}"; - - vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("policy", rules)); - - vaultOperations.write("secret/" + VaultConfigTlsCertAuthenticationMountPathTests.class.getSimpleName(), - Collections.singletonMap("vault.value", "foo")); - - File workDir = findWorkDir(); - - String certificate = Files.contentOf(new File(workDir, "ca/certs/client.cert.pem"), StandardCharsets.US_ASCII); - - Map role = new HashMap<>(); - role.put("certificate", certificate); - role.put("policies", "testpolicy"); - - vaultOperations.write(String.join("/", "auth", vaultProperties.getSsl().getCertAuthPath(), "certs", "my-role"), - role); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo("foo"); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTlsCertAuthenticationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTlsCertAuthenticationTests.java deleted file mode 100644 index 4c5b07ef..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigTlsCertAuthenticationTests.java +++ /dev/null @@ -1,112 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.io.File; -import java.nio.charset.StandardCharsets; -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.assertj.core.util.Files; -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.springframework.cloud.vault.util.Settings.findWorkDir; - -/** - * Integration test using config infrastructure with TLS certificate authentication. In - * case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigTlsCertAuthenticationTests.TestApplication.class, - properties = { "spring.cloud.vault.authentication=cert", - "spring.cloud.vault.ssl.key-store=file:../work/client-cert.jks", - "spring.cloud.vault.ssl.key-store-password=changeit", - "spring.cloud.vault.application-name=VaultConfigTlsCertAuthenticationTests", - "spring.cloud.vault.reactive.enabled=false", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigTlsCertAuthenticationTests { - - @Value("${vault.value}") - String configValue; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - VaultProperties vaultProperties = Settings.createVaultProperties(); - - if (!vaultRule.prepare().hasAuth(vaultProperties.getSsl().getCertAuthPath())) { - vaultRule.prepare().mountAuth(vaultProperties.getSsl().getCertAuthPath()); - } - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - String rules = "{ \"name\": \"testpolicy\",\n" // - + " \"path\": {\n" // - + " \"*\": { \"policy\": \"read\" }\n" // - + " }\n" // - + "}"; - - vaultOperations.write("sys/policy/testpolicy", Collections.singletonMap("rules", rules)); - - vaultOperations.write("secret/" + VaultConfigTlsCertAuthenticationTests.class.getSimpleName(), - Collections.singletonMap("vault.value", "foo")); - - File workDir = findWorkDir(); - - String certificate = Files.contentOf(new File(workDir, "ca/certs/client.cert.pem"), StandardCharsets.US_ASCII); - - Map role = new HashMap<>(); - role.put("certificate", certificate); - role.put("policies", "testpolicy"); - - vaultOperations.write("auth/cert/certs/my-role", role); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo("foo"); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigWithContextTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigWithContextTests.java deleted file mode 100644 index c21bd675..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigWithContextTests.java +++ /dev/null @@ -1,82 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test using config infrastructure with token authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigWithContextTests.TestApplication.class, - properties = { "spring.cloud.vault.application-name=testVaultApp", "spring.cloud.bootstrap.enabled=true" }) -@ActiveProfiles("my-profile") -public class VaultConfigWithContextTests { - - @Value("${vault.value}") - String configValue; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - vaultOperations.write("secret/testVaultApp/my-profile", Collections.singletonMap("vault.value", "hello")); - - vaultOperations.write("secret/testVaultApp", Collections.singletonMap("vault.value", "world")); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo("hello"); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigWithVaultConfigurerTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigWithVaultConfigurerTests.java deleted file mode 100644 index 87c5b867..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultConfigWithVaultConfigurerTests.java +++ /dev/null @@ -1,93 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.context.annotation.Bean; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test using config infrastructure with token authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultConfigWithVaultConfigurerTests.TestApplication.class, properties = { - "VaultConfigWithVaultConfigurerTests.custom.config=true", "spring.cloud.bootstrap.enabled=true" }) -public class VaultConfigWithVaultConfigurerTests { - - @Value("${vault.value}") - String configValue; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - VaultOperations vaultOperations = vaultRule.prepare().getVaultOperations(); - - vaultOperations.write("secret/VaultConfigWithVaultConfigurerTests", - Collections.singletonMap("vault.value", "hello")); - - vaultOperations.write("secret/testVaultApp", Collections.singletonMap("vault.value", "world")); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo("hello"); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - - public static class ConfigurerBootstrapApplication { - - @ConditionalOnProperty("VaultConfigWithVaultConfigurerTests.custom.config") - @Bean - VaultConfigurer vaultConfigurer() { - return configurer -> configurer.add("secret/VaultConfigWithVaultConfigurerTests"); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultHealthIndicatorAutoConfigurationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultHealthIndicatorAutoConfigurationTests.java deleted file mode 100644 index 5bb105f4..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultHealthIndicatorAutoConfigurationTests.java +++ /dev/null @@ -1,95 +0,0 @@ -/* - * Copyright 2020-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.junit.jupiter.api.Test; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.vault.core.ReactiveVaultOperations; -import org.springframework.vault.core.VaultOperations; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; - -/** - * Unit tests for {@link VaultHealthIndicatorAutoConfiguration}. - * - * @author Mark Paluch - * @author Rastislav Zlacky - */ -class VaultHealthIndicatorAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(VaultHealthIndicatorAutoConfiguration.class)); - - @Test - void shouldNotConfigureHealthIndicatorWithoutVaultOperations() { - - this.contextRunner.run(context -> { - assertThat(context).doesNotHaveBean("vaultHealthIndicator").doesNotHaveBean("vaultReactiveHealthIndicator"); - }); - } - - @Test - void shouldConfigureHealthIndicator() { - - this.contextRunner.withUserConfiguration(ImperativeConfiguration.class).run(context -> { - assertThat(context).hasBean("vaultHealthIndicator"); - }); - } - - @Test - void shouldConfigureReactiveHealthIndicator() { - - this.contextRunner.withUserConfiguration(ReactiveConfiguration.class).run(context -> { - assertThat(context).hasBean("vaultReactiveHealthIndicator"); - }); - - } - - @Test - void shouldConfigureSingleHealthIndicator() { - - this.contextRunner.withUserConfiguration(ImperativeConfiguration.class, ReactiveConfiguration.class) - .run(context -> { - assertThat(context).hasBean("vaultHealthIndicator") - .hasSingleBean(VaultReactiveHealthIndicator.class) - .doesNotHaveBean(VaultHealthIndicator.class); - }); - } - - static class ImperativeConfiguration { - - @Bean - VaultOperations vaultOperations() { - return mock(VaultOperations.class); - } - - } - - static class ReactiveConfiguration { - - @Bean - ReactiveVaultOperations reactiveVaultOperations() { - return mock(ReactiveVaultOperations.class); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultHealthIndicatorUnitTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultHealthIndicatorUnitTests.java deleted file mode 100644 index 98a6162c..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultHealthIndicatorUnitTests.java +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.core.VaultSysOperations; -import org.springframework.vault.support.VaultHealth; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.reset; -import static org.mockito.Mockito.when; - -/** - * Unit tests for {@link VaultHealthIndicator}. - * - * @author Mark Paluch - */ -@RunWith(MockitoJUnitRunner.class) -public class VaultHealthIndicatorUnitTests { - - @Mock - VaultOperations vaultOperations; - - @Mock - VaultSysOperations vaultSysOperations; - - @Mock - VaultHealth healthResponse; - - VaultHealthIndicator healthIndicator; - - @Before - public void before() { - - this.healthIndicator = new VaultHealthIndicator(this.vaultOperations); - - when(this.vaultOperations.opsForSys()).thenReturn(this.vaultSysOperations); - when(this.vaultSysOperations.health()).thenReturn(this.healthResponse); - } - - @Test - public void shouldReportHealthyService() { - - when(this.healthResponse.isInitialized()).thenReturn(true); - when(this.vaultOperations.opsForSys()).thenReturn(this.vaultSysOperations); - - Health health = this.healthIndicator.health(); - assertThat(health.getStatus()).isEqualTo(Status.UP); - assertThat(health.getDetails()).isEmpty(); - } - - @Test - public void shouldReportSealedService() { - - when(this.healthResponse.isInitialized()).thenReturn(true); - when(this.healthResponse.isSealed()).thenReturn(true); - - Health health = this.healthIndicator.health(); - - assertThat(health.getStatus()).isEqualTo(Status.DOWN); - assertThat(health.getDetails()).containsEntry("state", "Vault sealed"); - } - - @Test - public void shouldReportUninitializedService() { - - Health health = this.healthIndicator.health(); - - assertThat(health.getStatus()).isEqualTo(Status.DOWN); - assertThat(health.getDetails()).containsEntry("state", "Vault uninitialized"); - } - - @Test - public void shouldReportStandbyService() { - - when(this.healthResponse.isInitialized()).thenReturn(true); - when(this.healthResponse.isStandby()).thenReturn(true); - - Health health = this.healthIndicator.health(); - - assertThat(health.getStatus()).isEqualTo(Status.UP); - assertThat(health.getDetails()).containsEntry("state", "Vault in standby"); - } - - @Test - public void exceptionsShouldReportDownStatus() { - - reset(this.vaultSysOperations); - when(this.vaultSysOperations.health()).thenThrow(new IllegalStateException()); - - Health health = this.healthIndicator.health(); - assertThat(health.getStatus()).isEqualTo(Status.DOWN); - assertThat(health.getDetails()).containsKey("error"); - } - - @Test - public void shouldReportPerformanceStandby() { - - when(this.healthResponse.isInitialized()).thenReturn(true); - when(this.healthResponse.isPerformanceStandby()).thenReturn(true); - - Health health = this.healthIndicator.health(); - - assertThat(health.getStatus()).isEqualTo(Status.UP); - assertThat(health.getDetails()).containsEntry("state", "Vault in performance standby"); - } - - @Test - public void shouldReportRecoveryReplication() { - - when(this.healthResponse.isInitialized()).thenReturn(true); - when(this.healthResponse.isRecoveryReplicationSecondary()).thenReturn(true); - - Health health = this.healthIndicator.health(); - - assertThat(health.getStatus()).isEqualTo(Status.UP); - assertThat(health.getDetails()).containsEntry("state", "Vault in recovery replication secondary mode"); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultNamespaceTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultNamespaceTests.java deleted file mode 100644 index 3f00aa22..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultNamespaceTests.java +++ /dev/null @@ -1,143 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import org.junit.Assume; -import org.junit.Before; -import org.junit.ClassRule; -import org.junit.Test; -import org.junit.runner.RunWith; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.TestRestTemplateFactory; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.authentication.SimpleSessionManager; -import org.springframework.vault.authentication.TokenAuthentication; -import org.springframework.vault.client.ClientHttpConnectorFactory; -import org.springframework.vault.client.ClientHttpRequestFactoryFactory; -import org.springframework.vault.client.RestTemplateBuilder; -import org.springframework.vault.client.VaultHttpHeaders; -import org.springframework.vault.client.WebClientBuilder; -import org.springframework.vault.core.ReactiveVaultTemplate; -import org.springframework.vault.core.VaultSysOperations; -import org.springframework.vault.core.VaultTemplate; -import org.springframework.vault.support.ClientOptions; -import org.springframework.vault.support.Policy; -import org.springframework.vault.support.VaultMount; -import org.springframework.vault.support.VaultToken; -import org.springframework.vault.support.VaultTokenRequest; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for Vault's namespace feature. - */ -@RunWith(SpringRunner.class) -public class VaultNamespaceTests { - - @ClassRule - public static VaultRule vaultRule = new VaultRule(); - - static final Policy POLICY = Policy - .of(Policy.Rule.builder().path("/*").capabilities(Policy.BuiltinCapabilities.READ, - Policy.BuiltinCapabilities.CREATE, Policy.BuiltinCapabilities.UPDATE).build()); - - RestTemplateBuilder maketingRestTemplate; - - WebClientBuilder marketingWebClientBuilder = WebClientBuilder.builder() - .httpConnector(ClientHttpConnectorFactory.create(new ClientOptions(), Settings.createSslConfiguration())) - .endpoint(TestRestTemplateFactory.TEST_VAULT_ENDPOINT) - .defaultHeader(VaultHttpHeaders.VAULT_NAMESPACE, "marketing"); - - String marketingToken; - - @Before - public void before() { - Assume.assumeTrue("Namespaces require enterprise version", - this.vaultRule.prepare().getVersion().isEnterprise()); - - List namespaces = new ArrayList<>(Arrays.asList("dev/", "marketing/")); - List list = this.vaultRule.prepare().getVaultOperations().list("sys/namespaces"); - namespaces.removeAll(list); - - for (String namespace : namespaces) { - this.vaultRule.prepare().getVaultOperations().write("sys/namespaces/" + namespace.replaceAll("/", "")); - } - - this.maketingRestTemplate = RestTemplateBuilder.builder() - .requestFactory( - ClientHttpRequestFactoryFactory.create(new ClientOptions(), Settings.createSslConfiguration())) - .endpoint(TestRestTemplateFactory.TEST_VAULT_ENDPOINT) - .defaultHeader(VaultHttpHeaders.VAULT_NAMESPACE, "marketing"); - - VaultTemplate marketing = new VaultTemplate(this.maketingRestTemplate, - new SimpleSessionManager(new TokenAuthentication(Settings.token()))); - - mountKv(marketing, "marketing-secrets"); - marketing.opsForSys().createOrUpdatePolicy("relaxed", POLICY); - this.marketingToken = marketing.opsForToken().create(VaultTokenRequest.builder().withPolicy("relaxed").build()) - .getToken().getToken(); - } - - private void mountKv(VaultTemplate template, String path) { - - VaultSysOperations vaultSysOperations = template.opsForSys(); - - Map mounts = vaultSysOperations.getMounts(); - - if (!mounts.containsKey(path + "/")) { - vaultSysOperations.mount(path, - VaultMount.builder().type("kv").options(Collections.singletonMap("version", "1")).build()); - } - } - - @Test - public void shouldReportHealth() { - - VaultTemplate marketing = new VaultTemplate(this.maketingRestTemplate, - new SimpleSessionManager(new TokenAuthentication(this.marketingToken))); - - Health.Builder builder = Health.unknown(); - new VaultHealthIndicator(marketing).doHealthCheck(builder); - - assertThat(builder.build().getStatus()).isEqualTo(Status.UP); - } - - @Test - public void shouldReportReactiveHealth() { - - ReactiveVaultTemplate reactiveMarketing = new ReactiveVaultTemplate(this.marketingWebClientBuilder, - () -> Mono.just(VaultToken.of(this.marketingToken))); - - Health.Builder builder = Health.unknown(); - - new VaultReactiveHealthIndicator(reactiveMarketing).doHealthCheck(builder).as(StepVerifier::create) - .assertNext(actual -> assertThat(actual.getStatus()).isEqualTo(Status.UP)).verifyComplete(); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceIntegrationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceIntegrationTests.java deleted file mode 100644 index 3dc11923..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceIntegrationTests.java +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.Before; -import org.junit.Test; - -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.Version; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Integration tests for {@link VaultPropertySource}. - * - * @author Mark Paluch - */ -public class VaultPropertySourceIntegrationTests extends IntegrationTestSupport { - - @Before - public void before() { - prepare().getVaultOperations().write("secret/myapp", Collections.singletonMap("key", "value")); - } - - @Test - public void shouldReadValue() { - - VaultProperties vaultProperties = Settings.createVaultProperties(); - - VaultPropertySource propertySource = new VaultPropertySource( - new VaultConfigTemplate(prepare().getVaultOperations(), vaultProperties), false, - KeyValueSecretBackendMetadata.create("secret", "myapp")); - - propertySource.init(); - - assertThat(propertySource.getPropertyNames()).contains("key"); - assertThat(propertySource.getProperty("key")).isEqualTo("value"); - } - - @Test - public void shouldReadVersionedValue() { - - assumeTrue(this.vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.10.0"))); - - this.vaultRule.prepare().getVaultOperations().write("versioned/data/testVaultApp", - Collections.singletonMap("data", Collections.singletonMap("key", "value"))); - - VaultProperties vaultProperties = Settings.createVaultProperties(); - - VaultPropertySource propertySource = new VaultPropertySource( - new VaultConfigTemplate(prepare().getVaultOperations(), vaultProperties), false, - KeyValueSecretBackendMetadata.create("versioned", "testVaultApp")); - - propertySource.init(); - - assertThat(propertySource.getPropertyNames()).contains("key"); - assertThat(propertySource.getProperty("key")).isEqualTo("value"); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorIntegrationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorIntegrationTests.java deleted file mode 100644 index cf89bccd..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorIntegrationTests.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test incorporating loading secrets using - * {@code spring.cloud.vault.applicationName} and active profiles - * - * @author Ryan Hoegg - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultPropertySourceLocatorIntegrationTests.TestApplication.class, - properties = { "spring.cloud.vault.kv.application-name=neuromancer,icebreaker", - "spring.cloud.bootstrap.enabled=false", "spring.config.import=vault://" }) -@ActiveProfiles({ "integrationtest" }) -public class VaultPropertySourceLocatorIntegrationTests extends IntegrationTestSupport { - - @Value("${vault.value}") - String configValue; - - @Value("${icebreaker.value}") - String additionalValue; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - vaultRule.prepare().getVaultOperations().write("secret/wintermute", - Collections.singletonMap("vault.value", "wintermute")); - vaultRule.prepare().getVaultOperations().write("secret/wintermute/integrationtest", - Collections.singletonMap("vault.value", "integrationtest wintermute")); - - vaultRule.prepare().getVaultOperations().write("secret/neuromancer", - Collections.singletonMap("vault.value", "neuromancer")); - vaultRule.prepare().getVaultOperations().write("secret/neuromancer/integrationtest", - Collections.singletonMap("vault.value", "integrationtest neuromancer")); - - vaultRule.prepare().getVaultOperations().write("secret/icebreaker", - Collections.singletonMap("icebreaker.value", "icebreaker")); - vaultRule.prepare().getVaultOperations().write("secret/icebreaker/integrationtest", - Collections.singletonMap("icebreaker.value", "integrationtest icebreaker")); - } - - @Test - public void getsSecretFromVaultUsingVaultApplicationName() { - assertThat(this.configValue).isEqualTo("integrationtest neuromancer"); - } - - @Test - public void getsSecretFromVaultUsingAdditionalContext() { - assertThat(this.additionalValue).isEqualTo("integrationtest icebreaker"); - } - - @SpringBootApplication - public static class TestApplication { - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorProfilesIntegrationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorProfilesIntegrationTests.java deleted file mode 100644 index a5412487..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorProfilesIntegrationTests.java +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.core.env.Environment; -import org.springframework.test.context.ActiveProfiles; -import org.springframework.test.context.junit4.SpringRunner; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration test incorporating loading secrets using - * {@code spring.cloud.vault.kv.profiles}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultPropertySourceLocatorProfilesIntegrationTests.TestApplication.class, - properties = { "spring.application.name=my-profiles-app", "spring.cloud.vault.kv.profiles=hello, world", - "spring.cloud.vault.kv.default-context=", "spring.cloud.bootstrap.enabled=true" }) -@ActiveProfiles({ "other" }) -public class VaultPropertySourceLocatorProfilesIntegrationTests extends IntegrationTestSupport { - - @Autowired - Environment environment; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - vaultRule.prepare().getVaultOperations().write("secret/my-profiles-app/hello", - Collections.singletonMap("vault.hello", "true")); - - vaultRule.prepare().getVaultOperations().write("secret/my-profiles-app/world", - Collections.singletonMap("vault.world", "true")); - - vaultRule.prepare().getVaultOperations().write("secret/my-profiles-app/other", - Collections.singletonMap("vault.other", "true")); - } - - @Test - public void shouldContainValuesFromKvProfiles() { - assertThat(this.environment.getRequiredProperty("vault.hello")).isEqualTo("true"); - assertThat(this.environment.getRequiredProperty("vault.world")).isEqualTo("true"); - } - - @Test - public void shouldNotContainVaulesFromSpringProfiles() { - assertThat(this.environment.getProperty("vault.other")).isNull(); - } - - @SpringBootApplication - public static class TestApplication { - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorUnitTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorUnitTests.java deleted file mode 100644 index 6fccfabe..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultPropertySourceLocatorUnitTests.java +++ /dev/null @@ -1,173 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Arrays; - -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.mockito.Mock; -import org.mockito.junit.MockitoJUnitRunner; - -import org.springframework.core.annotation.Order; -import org.springframework.core.env.CompositePropertySource; -import org.springframework.core.env.ConfigurableEnvironment; -import org.springframework.core.env.PropertySource; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Unit tests for {@link VaultPropertySourceLocator}. - * - * @author Ryan Hoegg - * @author Mark Paluch - */ -@RunWith(MockitoJUnitRunner.class) -public class VaultPropertySourceLocatorUnitTests { - - private VaultPropertySourceLocator propertySourceLocator; - - @Mock - private VaultConfigTemplate operations; - - @Mock - private ConfigurableEnvironment configurableEnvironment; - - private VaultKeyValueBackendProperties properties = new VaultKeyValueBackendProperties(); - - @Before - public void before() { - this.propertySourceLocator = new VaultPropertySourceLocator(this.operations, new VaultProperties(), - VaultPropertySourceLocatorSupport.createConfiguration(this.properties)); - } - - @Test - public void getOrderShouldReturnConfiguredOrder() { - - VaultProperties vaultProperties = new VaultProperties(); - vaultProperties.getConfig().setOrder(42); - - this.propertySourceLocator = new VaultPropertySourceLocator(this.operations, vaultProperties, - VaultPropertySourceLocatorSupport.createConfiguration(new VaultKeyValueBackendProperties())); - - assertThat(this.propertySourceLocator.getOrder()).isEqualTo(42); - } - - @Test - public void shouldLocateOnePropertySourceWithEmptyProfiles() { - - PropertySource propertySource = this.propertySourceLocator.locate(this.configurableEnvironment); - - assertThat(propertySource).isInstanceOf(CompositePropertySource.class); - - CompositePropertySource composite = (CompositePropertySource) propertySource; - assertThat(composite.getPropertySources()).hasSize(1); - } - - @Test - public void shouldLocatePropertySourcesForActiveProfilesInDefaultContext() { - - this.properties.setProfiles(Arrays.asList("vermillion", "periwinkle")); - - PropertySource propertySource = this.propertySourceLocator.locate(this.configurableEnvironment); - - assertThat(propertySource).isInstanceOf(CompositePropertySource.class); - - CompositePropertySource composite = (CompositePropertySource) propertySource; - assertThat(composite.getPropertySources()).extracting("name").containsSequence("secret/application/periwinkle", - "secret/application/vermillion"); - } - - @Test - public void shouldLocatePropertySourcesInVaultApplicationContext() { - - VaultKeyValueBackendProperties backendProperties = new VaultKeyValueBackendProperties(); - backendProperties.setApplicationName("wintermute"); - backendProperties.setProfiles(Arrays.asList("vermillion", "periwinkle")); - - this.propertySourceLocator = new VaultPropertySourceLocator(this.operations, new VaultProperties(), - VaultPropertySourceLocatorSupport.createConfiguration(backendProperties)); - - PropertySource propertySource = this.propertySourceLocator.locate(this.configurableEnvironment); - - assertThat(propertySource).isInstanceOf(CompositePropertySource.class); - - CompositePropertySource composite = (CompositePropertySource) propertySource; - assertThat(composite.getPropertySources()).extracting("name").containsSequence("secret/wintermute/periwinkle", - "secret/wintermute/vermillion", "secret/wintermute"); - } - - @Test - public void shouldLocatePropertySourcesInEachPathSpecifiedWhenApplicationNameContainsSeveral() { - - VaultKeyValueBackendProperties backendProperties = new VaultKeyValueBackendProperties(); - backendProperties.setApplicationName("wintermute,straylight,icebreaker/armitage"); - backendProperties.setProfiles(Arrays.asList("vermillion", "periwinkle")); - - this.propertySourceLocator = new VaultPropertySourceLocator(this.operations, new VaultProperties(), - VaultPropertySourceLocatorSupport.createConfiguration(backendProperties)); - - PropertySource propertySource = this.propertySourceLocator.locate(this.configurableEnvironment); - - assertThat(propertySource).isInstanceOf(CompositePropertySource.class); - - CompositePropertySource composite = (CompositePropertySource) propertySource; - assertThat(composite.getPropertySources()).extracting("name").contains("secret/wintermute", "secret/straylight", - "secret/icebreaker/armitage", "secret/wintermute/vermillion", "secret/wintermute/periwinkle", - "secret/straylight/vermillion", "secret/straylight/periwinkle", "secret/icebreaker/armitage/vermillion", - "secret/icebreaker/armitage/periwinkle"); - } - - @Test - public void shouldCreatePropertySourcesInOrder() { - - DefaultSecretBackendConfigurer configurer = new DefaultSecretBackendConfigurer(); - configurer.add(new MySecondSecretBackendMetadata()); - configurer.add(new MyFirstSecretBackendMetadata()); - - this.propertySourceLocator = new VaultPropertySourceLocator(this.operations, new VaultProperties(), configurer); - - PropertySource propertySource = this.propertySourceLocator.locate(this.configurableEnvironment); - - assertThat(propertySource).isInstanceOf(CompositePropertySource.class); - - CompositePropertySource composite = (CompositePropertySource) propertySource; - assertThat(composite.getPropertySources()).extracting("name").containsSequence("foo", "bar"); - } - - @Order(1) - static class MyFirstSecretBackendMetadata extends SecretBackendMetadataSupport { - - @Override - public String getPath() { - return "foo"; - } - - } - - @Order(2) - static class MySecondSecretBackendMetadata extends SecretBackendMetadataSupport { - - @Override - public String getPath() { - return "bar"; - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultReactiveAutoConfigurationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultReactiveAutoConfigurationTests.java deleted file mode 100644 index dd8cd745..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultReactiveAutoConfigurationTests.java +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.time.Duration; -import java.util.concurrent.atomic.AtomicLong; - -import org.junit.Test; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.http.client.reactive.ClientHttpConnector; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.vault.authentication.AuthenticationSteps; -import org.springframework.vault.authentication.AuthenticationStepsFactory; -import org.springframework.vault.authentication.CachingVaultTokenSupplier; -import org.springframework.vault.authentication.LifecycleAwareSessionManager; -import org.springframework.vault.authentication.ReactiveSessionManager; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.authentication.SimpleSessionManager; -import org.springframework.vault.authentication.VaultTokenSupplier; -import org.springframework.vault.client.ReactiveVaultEndpointProvider; -import org.springframework.vault.client.VaultEndpoint; -import org.springframework.vault.client.WebClientFactory; -import org.springframework.vault.core.ReactiveVaultOperations; -import org.springframework.vault.core.ReactiveVaultTemplate; -import org.springframework.vault.support.VaultToken; -import org.springframework.web.reactive.function.client.WebClient; -import org.springframework.web.reactive.function.client.WebClientRequestException; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - -/** - * Tests for {@link VaultReactiveAutoConfiguration}. - * - * @author Mark Paluch - */ -public class VaultReactiveAutoConfigurationTests { - - private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(VaultReactiveAutoConfiguration.class)); - - @Test - public void shouldConfigureTemplate() { - - this.contextRunner.withUserConfiguration(AuthenticationFactoryConfiguration.class) - .withPropertyValues("spring.cloud.vault.session.lifecycle.enabled=false").run(context -> { - - assertThat(context).hasSingleBean(ReactiveVaultOperations.class); - assertThat(context).hasSingleBean(AuthenticationStepsFactory.class); - assertThat(context.getBean(SessionManager.class)).isNotNull() - .isNotInstanceOf(LifecycleAwareSessionManager.class) - .isNotInstanceOf(SimpleSessionManager.class); - assertThat(context.getBeanNamesForType(WebClient.class)).isEmpty(); - assertThat(context).hasSingleBean(WebClientFactory.class); - }); - } - - @Test - public void shouldNotConfigureIfHttpClientIsMissing() { - - this.contextRunner.withUserConfiguration(AuthenticationFactoryConfiguration.class) - .withClassLoader(new FilteredClassLoader("reactor.netty.http.client.HttpClient")).run(context -> { - - assertThat(context).doesNotHaveBean(ReactiveVaultOperations.class); - }); - } - - @Test - public void shouldConfigureTemplateWithTokenSupplier() { - - this.contextRunner.withUserConfiguration(TokenSupplierConfiguration.class) - .withPropertyValues("spring.cloud.vault.session.lifecycle.enabled=false").run(context -> { - - assertThat(context).hasSingleBean(ReactiveVaultOperations.class); - assertThat(context.getBean(SessionManager.class)).isNotNull() - .isNotInstanceOf(LifecycleAwareSessionManager.class) - .isNotInstanceOf(SimpleSessionManager.class); - assertThat(context).doesNotHaveBean(WebClient.class); - }); - } - - @Test - public void shouldNotConfigureReactiveSupport() { - - this.contextRunner.withUserConfiguration(VaultAutoConfiguration.class) - .withPropertyValues("spring.cloud.vault.reactive.enabled=false", "spring.cloud.vault.token=foo") - .run(context -> { - - assertThat(context).doesNotHaveBean(ReactiveVaultTemplate.class) - .doesNotHaveBean(ReactiveVaultOperations.class); - assertThat(context.getBean(SessionManager.class)).isInstanceOf(LifecycleAwareSessionManager.class); - }); - } - - @Test - public void sessionManagerBridgeShouldNotCacheTokens() { - - this.contextRunner.withUserConfiguration(TokenSupplierConfiguration.class, CustomSessionManager.class) - .run(context -> { - - SessionManager sessionManager = context.getBean(SessionManager.class); - - assertThat(sessionManager.getSessionToken().getToken()).isEqualTo("token-1"); - assertThat(sessionManager.getSessionToken().getToken()).isEqualTo("token-2"); - }); - } - - @Test - public void shouldDisableSessionManagement() { - - this.contextRunner - .withPropertyValues("spring.cloud.vault.kv.enabled=false", "spring.cloud.vault.token=foo", - "spring.cloud.vault.session.lifecycle.enabled=false") - .withBean("vaultTokenSupplier", VaultTokenSupplier.class, () -> Mono::empty) - .withBean("taskSchedulerWrapper", VaultAutoConfiguration.TaskSchedulerWrapper.class, - () -> new VaultAutoConfiguration.TaskSchedulerWrapper(new ThreadPoolTaskScheduler())) - .run(context -> { - - ReactiveSessionManager bean = context.getBean(ReactiveSessionManager.class); - assertThat(bean).isExactlyInstanceOf(CachingVaultTokenSupplier.class); - }); - } - - @Test - public void shouldConfigureSessionManagement() { - - this.contextRunner - .withPropertyValues("spring.cloud.vault.kv.enabled=false", "spring.cloud.vault.token=foo", - "spring.cloud.vault.session.lifecycle.refresh-before-expiry=11s", - "spring.cloud.vault.session.lifecycle.expiry-threshold=12s") - .withBean("vaultTokenSupplier", VaultTokenSupplier.class, () -> Mono::empty) - .withBean("taskSchedulerWrapper", VaultAutoConfiguration.TaskSchedulerWrapper.class, - () -> new VaultAutoConfiguration.TaskSchedulerWrapper(new ThreadPoolTaskScheduler())) - .run(context -> { - - ReactiveSessionManager bean = context.getBean(ReactiveSessionManager.class); - - Object refreshTrigger = ReflectionTestUtils.getField(bean, "refreshTrigger"); - - assertThat(refreshTrigger).hasFieldOrPropertyWithValue("duration", Duration.ofSeconds(11)) - .hasFieldOrPropertyWithValue("expiryThreshold", Duration.ofSeconds(12)); - }); - } - - @Test - public void shouldConfigureEndpointProvider() { - - this.contextRunner - .withPropertyValues("spring.cloud.vault.kv.enabled=false", "spring.cloud.vault.token=foo", - "spring.cloud.vault.session.lifecycle.enabled=false") - .withUserConfiguration(ReactiveEndpointProviderConfiguration.class) - .withBean("vaultTokenSupplier", VaultTokenSupplier.class, () -> Mono::empty) - .withBean("taskSchedulerWrapper", VaultAutoConfiguration.TaskSchedulerWrapper.class, - () -> new VaultAutoConfiguration.TaskSchedulerWrapper(new ThreadPoolTaskScheduler())) - .run(context -> { - - WebClientFactory factory = context.getBean(WebClientFactory.class); - WebClient webClient = factory.create(); - - webClient.get().uri("foo").retrieve().bodyToMono(String.class).as(StepVerifier::create) - .verifyErrorMatches(throwable -> throwable.getMessage().contains("foobar-1")); - - webClient.get().uri("foo").retrieve().bodyToMono(String.class).as(StepVerifier::create) - .verifyErrorMatches(throwable -> throwable.getMessage().contains("foobar-2")); - }); - } - - @Test - public void shouldConsiderCustomConnector() { - - this.contextRunner - .withPropertyValues("spring.cloud.vault.kv.enabled=false", "spring.cloud.vault.token=foo", - "spring.cloud.vault.session.lifecycle.enabled=false") - .withUserConfiguration(CustomConnector.class) - .withBean("vaultTokenSupplier", VaultTokenSupplier.class, - () -> () -> Mono.just(VaultToken.of("foo".toCharArray()))) - .withBean("taskSchedulerWrapper", VaultAutoConfiguration.TaskSchedulerWrapper.class, - () -> new VaultAutoConfiguration.TaskSchedulerWrapper(new ThreadPoolTaskScheduler())) - .run(context -> { - - ReactiveVaultOperations operations = context.getBean(ReactiveVaultOperations.class); - operations.delete("foo").as(StepVerifier::create).verifyError(WebClientRequestException.class); - }); - } - - @Configuration(proxyBeanMethods = false) - static class AuthenticationFactoryConfiguration { - - @Bean - AuthenticationStepsFactory authenticationStepsFactory() { - return () -> AuthenticationSteps.just(VaultToken.of("foo")); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TokenSupplierConfiguration { - - @Bean - VaultTokenSupplier vaultTokenSupplier() { - AtomicLong counter = new AtomicLong(); - return () -> Mono.just(VaultToken.of("token-" + counter.incrementAndGet())); - } - - } - - @Configuration - static class CustomSessionManager { - - @Bean - ReactiveSessionManager reactiveVaultSessionManager(VaultTokenSupplier tokenSupplier) { - return tokenSupplier::getVaultToken; - } - - } - - @Configuration(proxyBeanMethods = false) - static class ReactiveEndpointProviderConfiguration { - - @Bean - ReactiveVaultEndpointProvider reactiveVaultEndpointProvider() { - - AtomicLong counter = new AtomicLong(); - - return () -> Mono.fromSupplier(() -> { - - VaultEndpoint vaultEndpoint = new VaultEndpoint(); - vaultEndpoint.setHost("foobar-" + counter.incrementAndGet()); - - return vaultEndpoint; - }); - } - - } - - @Configuration(proxyBeanMethods = false) - static class CustomConnector { - - @Bean - VaultReactiveAutoConfiguration.ClientHttpConnectorWrapper myWrapper() { - ClientHttpConnector mock = mock(ClientHttpConnector.class); - when(mock.connect(any(), any(), any())).thenReturn(Mono.error(new UnsupportedOperationException())); - - return new VaultReactiveAutoConfiguration.ClientHttpConnectorWrapper(mock); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultReactiveBootstrapConfigurationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultReactiveBootstrapConfigurationTests.java deleted file mode 100644 index edaed107..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultReactiveBootstrapConfigurationTests.java +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright 2017-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.time.Duration; -import java.util.concurrent.atomic.AtomicLong; - -import org.junit.Test; -import reactor.core.publisher.Mono; - -import org.springframework.boot.autoconfigure.AutoConfigurations; -import org.springframework.boot.test.context.FilteredClassLoader; -import org.springframework.boot.test.context.runner.ApplicationContextRunner; -import org.springframework.context.annotation.Bean; -import org.springframework.context.annotation.Configuration; -import org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler; -import org.springframework.test.util.ReflectionTestUtils; -import org.springframework.vault.authentication.AuthenticationSteps; -import org.springframework.vault.authentication.AuthenticationStepsFactory; -import org.springframework.vault.authentication.CachingVaultTokenSupplier; -import org.springframework.vault.authentication.LifecycleAwareSessionManager; -import org.springframework.vault.authentication.ReactiveSessionManager; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.authentication.SimpleSessionManager; -import org.springframework.vault.authentication.VaultTokenSupplier; -import org.springframework.vault.client.WebClientFactory; -import org.springframework.vault.core.ReactiveVaultOperations; -import org.springframework.vault.core.ReactiveVaultTemplate; -import org.springframework.vault.support.VaultToken; -import org.springframework.web.reactive.function.client.WebClient; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Tests for {@link VaultReactiveBootstrapConfiguration}. - * - * @author Mark Paluch - */ -public class VaultReactiveBootstrapConfigurationTests { - - private ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withConfiguration(AutoConfigurations.of(VaultReactiveBootstrapConfiguration.class)) - .withAllowBeanDefinitionOverriding(true); - - @Test - public void shouldConfigureTemplate() { - - this.contextRunner.withUserConfiguration(AuthenticationFactoryConfiguration.class) - .withPropertyValues("spring.cloud.vault.session.lifecycle.enabled=false", - "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - assertThat(context).hasSingleBean(ReactiveVaultOperations.class); - assertThat(context).hasSingleBean(AuthenticationStepsFactory.class); - assertThat(context.getBean(SessionManager.class)).isNotNull() - .isNotInstanceOf(LifecycleAwareSessionManager.class) - .isNotInstanceOf(SimpleSessionManager.class); - assertThat(context.getBeanNamesForType(WebClient.class)).isEmpty(); - assertThat(context).hasSingleBean(WebClientFactory.class); - }); - } - - @Test - public void shouldNotConfigureIfHttpClientIsMissing() { - - this.contextRunner.withUserConfiguration(AuthenticationFactoryConfiguration.class) - .withClassLoader(new FilteredClassLoader("reactor.netty.http.client.HttpClient")).run(context -> { - - assertThat(context).doesNotHaveBean(ReactiveVaultOperations.class); - }); - } - - @Test - public void shouldConfigureTemplateWithTokenSupplier() { - - this.contextRunner.withUserConfiguration(TokenSupplierConfiguration.class) - .withPropertyValues("spring.cloud.vault.session.lifecycle.enabled=false", - "spring.cloud.bootstrap.enabled=true") - .run(context -> { - - assertThat(context).hasSingleBean(ReactiveVaultOperations.class); - assertThat(context.getBean(SessionManager.class)).isNotNull() - .isNotInstanceOf(LifecycleAwareSessionManager.class) - .isNotInstanceOf(SimpleSessionManager.class); - assertThat(context).doesNotHaveBean(WebClient.class); - }); - } - - @Test - public void shouldNotConfigureReactiveSupport() { - - this.contextRunner.withUserConfiguration(VaultBootstrapConfiguration.class) - .withPropertyValues("spring.cloud.vault.reactive.enabled=false", "spring.cloud.vault.token=foo") - .run(context -> { - - assertThat(context).doesNotHaveBean(ReactiveVaultTemplate.class) - .doesNotHaveBean(ReactiveVaultOperations.class); - assertThat(context.getBean(SessionManager.class)).isInstanceOf(LifecycleAwareSessionManager.class); - }); - } - - @Test - public void sessionManagerBridgeShouldNotCacheTokens() { - - this.contextRunner.withUserConfiguration(TokenSupplierConfiguration.class, CustomSessionManager.class) - .run(context -> { - - SessionManager sessionManager = context.getBean(SessionManager.class); - - assertThat(sessionManager.getSessionToken().getToken()).isEqualTo("token-1"); - assertThat(sessionManager.getSessionToken().getToken()).isEqualTo("token-2"); - }); - } - - @Test - public void shouldDisableSessionManagement() { - - this.contextRunner - .withPropertyValues("spring.cloud.vault.kv.enabled=false", "spring.cloud.vault.token=foo", - "spring.cloud.vault.session.lifecycle.enabled=false") - .withBean("vaultTokenSupplier", VaultTokenSupplier.class, () -> Mono::empty) - .withBean("taskSchedulerWrapper", VaultBootstrapConfiguration.TaskSchedulerWrapper.class, - () -> new VaultBootstrapConfiguration.TaskSchedulerWrapper(new ThreadPoolTaskScheduler())) - .run(context -> { - - ReactiveSessionManager bean = context.getBean(ReactiveSessionManager.class); - assertThat(bean).isExactlyInstanceOf(CachingVaultTokenSupplier.class); - }); - } - - @Test - public void shouldConfigureSessionManagement() { - - this.contextRunner - .withPropertyValues("spring.cloud.vault.kv.enabled=false", "spring.cloud.vault.token=foo", - "spring.cloud.vault.session.lifecycle.refresh-before-expiry=11s", - "spring.cloud.vault.session.lifecycle.expiry-threshold=12s") - .withBean("vaultTokenSupplier", VaultTokenSupplier.class, () -> Mono::empty) - .withBean("taskSchedulerWrapper", VaultBootstrapConfiguration.TaskSchedulerWrapper.class, - () -> new VaultBootstrapConfiguration.TaskSchedulerWrapper(new ThreadPoolTaskScheduler())) - .run(context -> { - - ReactiveSessionManager bean = context.getBean(ReactiveSessionManager.class); - - Object refreshTrigger = ReflectionTestUtils.getField(bean, "refreshTrigger"); - - assertThat(refreshTrigger).hasFieldOrPropertyWithValue("duration", Duration.ofSeconds(11)) - .hasFieldOrPropertyWithValue("expiryThreshold", Duration.ofSeconds(12)); - }); - } - - @Configuration(proxyBeanMethods = false) - static class AuthenticationFactoryConfiguration { - - @Bean - AuthenticationStepsFactory authenticationStepsFactory() { - return () -> AuthenticationSteps.just(VaultToken.of("foo")); - } - - } - - @Configuration(proxyBeanMethods = false) - static class TokenSupplierConfiguration { - - @Bean - VaultTokenSupplier vaultTokenSupplier() { - AtomicLong counter = new AtomicLong(); - return () -> Mono.just(VaultToken.of("token-" + counter.incrementAndGet())); - } - - } - - @Configuration - static class CustomSessionManager { - - @Bean - ReactiveSessionManager reactiveVaultSessionManager(VaultTokenSupplier tokenSupplier) { - return tokenSupplier::getVaultToken; - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultReactiveHealthIndicatorIntegrationTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultReactiveHealthIndicatorIntegrationTests.java deleted file mode 100644 index b760f35d..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultReactiveHealthIndicatorIntegrationTests.java +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2019-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import org.junit.Test; -import reactor.core.publisher.Mono; -import reactor.test.StepVerifier; - -import org.springframework.boot.actuate.health.Health; -import org.springframework.boot.actuate.health.Status; -import org.springframework.cloud.vault.util.IntegrationTestSupport; -import org.springframework.cloud.vault.util.Settings; -import org.springframework.cloud.vault.util.TestRestTemplateFactory; -import org.springframework.vault.client.ClientHttpConnectorFactory; -import org.springframework.vault.core.ReactiveVaultTemplate; -import org.springframework.vault.support.ClientOptions; - -import static org.assertj.core.api.Assertions.assertThat; - -/** - * Integration tests for {@link VaultReactiveHealthIndicator}. - * - * @author Mark Paluch - */ -public class VaultReactiveHealthIndicatorIntegrationTests extends IntegrationTestSupport { - - @Test - public void shouldReturnHealthState() { - - ReactiveVaultTemplate vaultTemplate = new ReactiveVaultTemplate(TestRestTemplateFactory.TEST_VAULT_ENDPOINT, - ClientHttpConnectorFactory.create(new ClientOptions(), Settings.createSslConfiguration()), - () -> Mono.just(Settings.token())); - - VaultReactiveHealthIndicator healthIndicator = new VaultReactiveHealthIndicator(vaultTemplate); - - healthIndicator.doHealthCheck(Health.up()).as(StepVerifier::create).consumeNextWith(actual -> { - assertThat(actual.getStatus()).isEqualTo(Status.UP); - }).verifyComplete(); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultVersionedKvBackendConfigTests.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultVersionedKvBackendConfigTests.java deleted file mode 100644 index 13d89655..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/config/VaultVersionedKvBackendConfigTests.java +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Copyright 2018-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.config; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import org.junit.BeforeClass; -import org.junit.Test; -import org.junit.runner.RunWith; - -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.SpringApplication; -import org.springframework.boot.autoconfigure.SpringBootApplication; -import org.springframework.boot.test.context.SpringBootTest; -import org.springframework.cloud.vault.util.VaultRule; -import org.springframework.cloud.vault.util.Version; -import org.springframework.context.ApplicationContext; -import org.springframework.core.env.Environment; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.test.context.junit4.SpringRunner; -import org.springframework.vault.core.VaultTemplate; -import org.springframework.web.client.RestTemplate; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.Assume.assumeTrue; - -/** - * Integration test using config infrastructure with token authentication. - * - *

- * In case this test should fail because of SSL make sure you run the test within the - * spring-cloud-vault-config/spring-cloud-vault-config directory as the keystore is - * referenced with {@code ../work/keystore.jks}. - * - * @author Mark Paluch - */ -@RunWith(SpringRunner.class) -@SpringBootTest(classes = VaultVersionedKvBackendConfigTests.TestApplication.class, - properties = { "spring.cloud.vault.host=foo", "spring.cloud.vault.port=80", - "spring.cloud.vault.uri=https://localhost:8200", "spring.cloud.vault.kv.enabled=true", - "spring.cloud.vault.kv.backend=versioned", "spring.cloud.vault.application-name=testVaultApp", - "spring.cloud.bootstrap.enabled=true" }) -public class VaultVersionedKvBackendConfigTests { - - @Value("${vault.value}") - String configValue; - - @Autowired - Environment environment; - - @Autowired - ApplicationContext applicationContext; - - @BeforeClass - public static void beforeClass() { - - VaultRule vaultRule = new VaultRule(); - vaultRule.before(); - - assumeTrue(vaultRule.prepare().getVersion().isGreaterThanOrEqualTo(Version.parse("0.10.0"))); - - Map object = new HashMap<>(); - object.put("vault.value", "foo"); - object.put("nested", Collections.singletonMap("key", "value")); - - vaultRule.prepare().getVaultOperations().write("versioned/data/testVaultApp", - Collections.singletonMap("data", object)); - } - - @Test - public void contextLoads() { - assertThat(this.configValue).isEqualTo("foo"); - } - - @Test - public void shouldContainProperty() { - - assertThat(this.environment.containsProperty("vault.value")).isTrue(); - assertThat(this.environment.getProperty("vault.value")).isEqualTo("foo"); - - assertThat(this.environment.containsProperty("nested.key")).isTrue(); - assertThat(this.environment.getProperty("nested.key")).isEqualTo("value"); - } - - @Test - public void shouldContainVaultBeans() { - - // Beans are registered in parent (bootstrap) context. - ApplicationContext parent = this.applicationContext.getParent(); - - assertThat(parent.getBeanNamesForType(VaultTemplate.class)).isNotEmpty(); - assertThat(parent.getBeanNamesForType(LeasingVaultPropertySourceLocator.class)).isNotEmpty(); - } - - @Test - public void shouldNotContainRestTemplateArtifacts() { - - // Beans are registered in parent (bootstrap) context. - ApplicationContext parent = this.applicationContext.getParent(); - - assertThat(parent.getBeanNamesForType(RestTemplate.class)).isEmpty(); - assertThat(parent.getBeanNamesForType(ClientHttpRequestFactory.class)).isEmpty(); - } - - @SpringBootApplication - public static class TestApplication { - - public static void main(String[] args) { - SpringApplication.run(TestApplication.class, args); - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/CanConnect.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/CanConnect.java deleted file mode 100644 index a38f1012..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/CanConnect.java +++ /dev/null @@ -1,49 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.util; - -import java.io.IOException; -import java.net.Socket; -import java.net.SocketAddress; -import java.util.concurrent.TimeUnit; - -/** - * Helper to check whether a TCP connection can be established. - * - * @author Mark Paluch - */ -public class CanConnect { - - /** - * Performs a check whether a connection can be established to the - * {@code socketAddress}. - * @param socketAddress the address to test, must not be {@literal null}. - * @return {@literal true}, if a connection can be established - */ - public static boolean to(SocketAddress socketAddress) { - - try (Socket socket = new Socket()) { - - socket.connect(socketAddress, (int) TimeUnit.SECONDS.toMillis(1)); - return true; - } - catch (IOException e) { - return false; - } - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/IntegrationTestSupport.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/IntegrationTestSupport.java deleted file mode 100644 index f374cb8e..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/IntegrationTestSupport.java +++ /dev/null @@ -1,35 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.util; - -import org.junit.Rule; - -/** - * Base class for integration tests using Vault. - * - * @author Mark Paluch - */ -public abstract class IntegrationTestSupport { - - @Rule - public final VaultRule vaultRule = new VaultRule(); - - public final PrepareVault prepare() { - return this.vaultRule.prepare(); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/PrepareVault.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/PrepareVault.java deleted file mode 100644 index 99c57c30..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/PrepareVault.java +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.util; - -import java.util.Collections; -import java.util.Map; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; -import org.springframework.vault.core.VaultOperations; -import org.springframework.vault.core.VaultSysOperations; -import org.springframework.vault.support.VaultHealth; -import org.springframework.vault.support.VaultInitializationRequest; -import org.springframework.vault.support.VaultInitializationResponse; -import org.springframework.vault.support.VaultMount; -import org.springframework.vault.support.VaultToken; -import org.springframework.vault.support.VaultTokenRequest; -import org.springframework.vault.support.VaultTokenRequest.VaultTokenRequestBuilder; -import org.springframework.vault.support.VaultTokenResponse; -import org.springframework.vault.support.VaultUnsealStatus; - -/** - * @author Mark Paluch - */ -public class PrepareVault { - - private final VaultOperations vaultOperations; - - private final VaultSysOperations adminOperations; - - public PrepareVault(VaultOperations vaultOperations) { - - this.vaultOperations = vaultOperations; - this.adminOperations = vaultOperations.opsForSys(); - } - - /** - * Initialize Vault and unseal the vault. - * @return the root token. - */ - public VaultToken initializeVault() { - - int createKeys = 2; - int requiredKeys = 2; - - VaultInitializationResponse initialized = this.vaultOperations.opsForSys() - .initialize(VaultInitializationRequest.create(createKeys, requiredKeys)); - - for (int i = 0; i < requiredKeys; i++) { - - VaultUnsealStatus unsealStatus = this.vaultOperations.opsForSys().unseal(initialized.getKeys().get(i)); - - if (!unsealStatus.isSealed()) { - break; - } - } - - return initialized.getRootToken(); - } - - /** - * Create a token for the given {@code tokenId} and {@code policy}. - * @param tokenId the must not be {@literal null}. - * @param policy the must not be {@literal null}. - * @return the token. - */ - public VaultToken createToken(String tokenId, String policy) { - - VaultTokenRequestBuilder builder = VaultTokenRequest.builder().id(tokenId); - - if (StringUtils.hasText(policy)) { - builder.withPolicy(policy); - } - - VaultTokenResponse vaultTokenResponse = this.vaultOperations.opsForToken().create(builder.build()); - return vaultTokenResponse.getToken(); - } - - /** - * Check whether Vault is available (vault created and unsealed). - * @return whether Vault is available. - */ - public boolean isAvailable() { - return this.adminOperations.isInitialized() && !this.adminOperations.health().isSealed(); - } - - /** - * Mount an auth backend. - * @param authBackend the must not be {@literal null}. - */ - public void mountAuth(String authBackend) { - - Assert.hasText(authBackend, "AuthBackend must not be empty"); - - this.adminOperations.authMount(authBackend, VaultMount.create(authBackend)); - } - - /** - * Check whether a auth-backend is enabled. - * @param authBackend the must not be {@literal null}. - * @return whether the backend is mounted. - */ - public boolean hasAuth(String authBackend) { - - Assert.hasText(authBackend, "AuthBackend must not be empty"); - - return this.adminOperations.getAuthMounts().containsKey(authBackend + "/"); - } - - /** - * Mount an secret backend. - * @param secretBackend must not be {@literal null} or empty. - */ - public void mountSecret(String secretBackend) { - mountSecret(secretBackend, secretBackend, Collections.emptyMap()); - } - - /** - * Mount an secret backend {@code secretBackend} at {@code path}. - * @param secretBackend must not be {@literal null} or empty. - * @param path must not be {@literal null} or empty. - * @param config must not be {@literal null}. - */ - public void mountSecret(String secretBackend, String path, Map config) { - - Assert.hasText(secretBackend, "SecretBackend must not be empty"); - Assert.hasText(path, "Mount path must not be empty"); - Assert.notNull(config, "Configuration must not be null"); - - VaultMount mount = VaultMount.builder().type(secretBackend).config(config).build(); - this.adminOperations.mount(path, mount); - } - - /** - * Check whether a auth-backend is enabled. - * @param secretBackend the must not be {@literal null}. - * @return whether the backend is mounted. - */ - public boolean hasSecretBackend(String secretBackend) { - - Assert.hasText(secretBackend, "SecretBackend must not be empty"); - Map mounts = this.adminOperations.getMounts(); - return mounts.containsKey(secretBackend) || mounts.containsKey(secretBackend + "/"); - } - - public VaultOperations getVaultOperations() { - return this.vaultOperations; - } - - /** - * @return Vault version from the health check. Versions beginning from Vault 0.6.2 - * will expose a version number. - */ - public Version getVersion() { - - VaultHealth health = getVaultOperations().opsForSys().health(); - - if (StringUtils.hasText(health.getVersion())) { - - String version = health.getVersion(); - - // Migration code for Vault 0.6.1 - if (version.startsWith("Vault v")) { - version = version.substring(7); - } - - return Version.parse(version); - } - - return Version.parse("0.0.0"); - } - - /** - * Disable Vault versioning Key-Value backend (kv version 2). - */ - public void disableGenericVersioning() { - - this.vaultOperations.opsForSys().unmount("secret"); - - VaultMount kv = VaultMount.builder().type("kv").config(Collections.singletonMap("versioned", false)).build(); - this.vaultOperations.opsForSys().mount("secret", kv); - } - - public void mountVersionedKvBackend() { - - mountSecret("kv", "versioned", Collections.emptyMap()); - this.vaultOperations.write("sys/mounts/versioned/tune", - Collections.singletonMap("options", Collections.singletonMap("version", "2"))); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/Settings.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/Settings.java deleted file mode 100644 index c19a4531..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/Settings.java +++ /dev/null @@ -1,99 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.util; - -import java.io.File; - -import org.springframework.cloud.vault.config.VaultProperties; -import org.springframework.core.io.FileSystemResource; -import org.springframework.vault.support.SslConfiguration; -import org.springframework.vault.support.VaultToken; - -/** - * Utility to retrieve settings during test. - * - * @author Mark Paluch - */ -public class Settings { - - /** - * @return the vault properties. - */ - public static VaultProperties createVaultProperties() { - - File workDir = findWorkDir(); - - VaultProperties vaultProperties = new VaultProperties(); - vaultProperties.getSsl().setTrustStorePassword("changeit"); - vaultProperties.getSsl().setTrustStore(new FileSystemResource(new File(workDir, "keystore.jks"))); - vaultProperties.setToken(token().getToken()); - - return vaultProperties; - } - - /** - * @return the vault properties. - */ - public static SslConfiguration createSslConfiguration() { - - File workDir = findWorkDir(); - - return SslConfiguration.forTrustStore(new FileSystemResource(new File(workDir, "keystore.jks")), - "changeit".toCharArray()); - } - - /** - * Find the {@code work} directory, starting at the {@code user.dir} directory. Search - * is performed by walking the parent directories. - * @return the {@link File} pointing to the {@code work} directory - * @throws IllegalStateException If the {@code work} directory cannot be found. - */ - public static File findWorkDir() { - return findWorkDir(new File(System.getProperty("user.dir"))); - } - - /** - * Find the {@code work} directory, starting at the given {@code directory}. Search is - * performed by walking the parent directories. - * @return the {@link File} pointing to the {@code work} directory - * @throws IllegalStateException If the {@code work} directory cannot be found. - */ - public static File findWorkDir(File directory) { - - File searchLevel = directory; - while (searchLevel.getParentFile() != null && searchLevel.getParentFile() != searchLevel) { - - File work = new File(searchLevel, "work"); - if (work.isDirectory() && work.exists()) { - return work; - } - - searchLevel = searchLevel.getParentFile(); - } - - throw new IllegalStateException(String.format("Cannot find work directory in %s or any parent directories", - directory.getAbsoluteFile())); - } - - /** - * @return the token to use during tests. - */ - public static VaultToken token() { - return VaultToken.of(System.getProperty("vault.token", "00000000-0000-0000-0000-000000000000")); - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/TestRestTemplateFactory.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/TestRestTemplateFactory.java deleted file mode 100644 index 68e3ad29..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/TestRestTemplateFactory.java +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.util; - -import java.util.concurrent.atomic.AtomicReference; - -import org.springframework.beans.factory.DisposableBean; -import org.springframework.beans.factory.InitializingBean; -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.util.Assert; -import org.springframework.vault.client.ClientHttpRequestFactoryFactory; -import org.springframework.vault.client.VaultClients; -import org.springframework.vault.client.VaultEndpoint; -import org.springframework.vault.support.ClientOptions; -import org.springframework.vault.support.SslConfiguration; -import org.springframework.web.client.RestTemplate; - -/** - * Factory for {@link RestTemplate}. The template caches the - * {@link ClientHttpRequestFactory} once it was initialized. Changes to timeouts or the - * SSL configuration won't be applied once a {@link ClientHttpRequestFactory} was created - * for the first time. - * - * @author Mark Paluch - */ -public class TestRestTemplateFactory { - - public static final VaultEndpoint TEST_VAULT_ENDPOINT = new VaultEndpoint(); - - private static final AtomicReference factoryCache = new AtomicReference<>(); - - /** - * Create a new {@link RestTemplate} using the {@link SslConfiguration}. The - * underlying {@link ClientHttpRequestFactory} is cached. See - * {@link #create(ClientHttpRequestFactory)} to create {@link RestTemplate} for a - * given {@link ClientHttpRequestFactory}. - * @param sslConfiguration must not be {@literal null}. - * @return the configured {@link RestTemplate}. - */ - public static RestTemplate create(SslConfiguration sslConfiguration) { - - Assert.notNull(sslConfiguration, "SslConfiguration must not be null!"); - - try { - initializeClientHttpRequestFactory(sslConfiguration); - return create(factoryCache.get()); - } - catch (Exception e) { - throw new IllegalStateException(e); - } - } - - /** - * Create a new {@link RestTemplate} using the {@link ClientHttpRequestFactory}. The - * {@link RestTemplate} will throw - * {@link org.springframework.web.client.HttpStatusCodeException exceptions} in error - * cases and behave in that aspect like the regular {@link RestTemplate}. - * @param requestFactory must not be {@literal null}. - * @return the configured {@link RestTemplate}. - */ - public static RestTemplate create(ClientHttpRequestFactory requestFactory) { - - Assert.notNull(requestFactory, "ClientHttpRequestFactory must not be null!"); - - return VaultClients.createRestTemplate(TEST_VAULT_ENDPOINT, requestFactory); - } - - private static void initializeClientHttpRequestFactory(SslConfiguration sslConfiguration) throws Exception { - - if (factoryCache.get() != null) { - return; - } - - final ClientHttpRequestFactory clientHttpRequestFactory = ClientHttpRequestFactoryFactory - .create(new ClientOptions(), sslConfiguration); - - if (factoryCache.compareAndSet(null, clientHttpRequestFactory)) { - - if (clientHttpRequestFactory instanceof InitializingBean) { - ((InitializingBean) clientHttpRequestFactory).afterPropertiesSet(); - } - - if (clientHttpRequestFactory instanceof DisposableBean) { - - Runtime.getRuntime().addShutdownHook(new Thread("ClientHttpRequestFactory Shutdown Hook") { - - @Override - public void run() { - try { - ((DisposableBean) clientHttpRequestFactory).destroy(); - } - catch (Exception e) { - e.printStackTrace(); - } - } - }); - } - } - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/VaultRule.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/VaultRule.java deleted file mode 100644 index b8845980..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/VaultRule.java +++ /dev/null @@ -1,118 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.util; - -import java.net.InetAddress; -import java.net.InetSocketAddress; -import java.net.Socket; - -import org.junit.rules.ExternalResource; - -import org.springframework.http.client.ClientHttpRequestFactory; -import org.springframework.util.Assert; -import org.springframework.vault.authentication.SessionManager; -import org.springframework.vault.client.VaultEndpoint; -import org.springframework.vault.core.VaultTemplate; -import org.springframework.vault.support.SslConfiguration; -import org.springframework.vault.support.VaultToken; - -/** - * Vault rule to ensure a running and prepared Vault. - * - * @author Mark Paluch - */ -public class VaultRule extends ExternalResource { - - public static final Version VERSIONING_INTRODUCED_WITH = Version.parse("0.10.0"); - - private final VaultEndpoint vaultEndpoint; - - private final PrepareVault prepareVault; - - private VaultToken token; - - /** - * Create a new {@link VaultRule} with default SSL configuration and endpoint. - * - * @see Settings#createSslConfiguration() - * @see VaultEndpoint - */ - public VaultRule() { - this(Settings.createSslConfiguration(), TestRestTemplateFactory.TEST_VAULT_ENDPOINT); - } - - /** - * Create a new {@link VaultRule} with the given {@link SslConfiguration} and - * {@link VaultEndpoint}. - * @param sslConfiguration must not be {@literal null}. - * @param vaultEndpoint must not be {@literal null}. - */ - public VaultRule(SslConfiguration sslConfiguration, VaultEndpoint vaultEndpoint) { - - Assert.notNull(sslConfiguration, "SslConfiguration must not be null"); - Assert.notNull(vaultEndpoint, "VaultEndpoint must not be null"); - - ClientHttpRequestFactory requestFactory = TestRestTemplateFactory.create(sslConfiguration).getRequestFactory(); - - VaultTemplate vaultTemplate = new VaultTemplate(vaultEndpoint, requestFactory, new PreparingSessionManager()); - - this.token = Settings.token(); - this.prepareVault = new PrepareVault(vaultTemplate); - this.vaultEndpoint = vaultEndpoint; - } - - @Override - public void before() { - - try (Socket socket = new Socket()) { - - socket.connect(new InetSocketAddress(InetAddress.getByName("localhost"), this.vaultEndpoint.getPort())); - } - catch (Exception ex) { - throw new IllegalStateException( - String.format("Vault is not running on localhost:%d which is required to run a test using @Rule %s", - this.vaultEndpoint.getPort(), getClass().getSimpleName())); - } - - if (!this.prepareVault.isAvailable()) { - - this.token = this.prepareVault.initializeVault(); - this.prepareVault.createToken(Settings.token().getToken(), "root"); - - if (this.prepareVault.getVersion().isGreaterThanOrEqualTo(VERSIONING_INTRODUCED_WITH)) { - this.prepareVault.disableGenericVersioning(); - this.prepareVault.mountVersionedKvBackend(); - } - - this.token = Settings.token(); - } - } - - public PrepareVault prepare() { - return this.prepareVault; - } - - private class PreparingSessionManager implements SessionManager { - - @Override - public VaultToken getSessionToken() { - return VaultRule.this.token; - } - - } - -} diff --git a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/Version.java b/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/Version.java deleted file mode 100644 index a6eaafd0..00000000 --- a/spring-cloud-vault-config/src/test/java/org/springframework/cloud/vault/util/Version.java +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 2016-2021 the original author or authors. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * https://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.springframework.cloud.vault.util; - -import java.util.ArrayList; -import java.util.List; -import java.util.Objects; - -import org.springframework.util.Assert; -import org.springframework.util.StringUtils; - -/** - * Value object representing Version consisting of major, minor and bugfix part. - * - * @author Mark Paluch - */ -public final class Version implements Comparable { - - private static final String VERSION_PARSE_ERROR = "Invalid version string! Could not parse segment %s within %s."; - - private final int major; - - private final int minor; - - private final int bugfix; - - private final int build; - - private final boolean enterprise; - - /** - * Creates a new {@link Version} from the given integer values. At least one value has - * to be given but a maximum of 4. - * @param parts must not be {@literal null} or empty. - */ - private Version(boolean enterprise, int... parts) { - - Assert.notNull(parts, "Parts must not be null!"); - Assert.isTrue(parts.length > 0 && parts.length < 5, "Parts must contain 1 to 5 segments!"); - - this.major = parts[0]; - this.minor = parts.length > 1 ? parts[1] : 0; - this.bugfix = parts.length > 2 ? parts[2] : 0; - this.build = parts.length > 3 ? parts[3] : 0; - this.enterprise = enterprise; - - Assert.isTrue(this.major >= 0, "Major version must be greater or equal zero!"); - Assert.isTrue(this.minor >= 0, "Minor version must be greater or equal zero!"); - Assert.isTrue(this.bugfix >= 0, "Bugfix version must be greater or equal zero!"); - Assert.isTrue(this.build >= 0, "Build version must be greater or equal zero!"); - } - - /** - * Parses the given string representation of a version into a {@link Version} object. - * @param version must not be {@literal null} or empty. - * @return the version. - */ - public static Version parse(String version) { - - Assert.hasText(version, "Version must not be empty"); - - String[] parts = version.trim().split("\\."); - int[] intParts = new int[parts.length]; - boolean enterprise = version.endsWith("+ent"); - - for (int i = 0; i < parts.length; i++) { - - String input = i == parts.length - 1 ? parts[i].replaceAll("\\D.*", "") : parts[i]; - - if (StringUtils.hasText(input)) { - try { - intParts[i] = Integer.parseInt(input); - } - catch (IllegalArgumentException o_O) { - throw new IllegalArgumentException(String.format(VERSION_PARSE_ERROR, input, version), o_O); - } - } - } - - return new Version(enterprise, intParts); - } - - /** - * Returns whether the current {@link Version} is greater (newer) than the given one. - * @param version must not be {@literal null}. - * @return comparison result. - */ - public boolean isGreaterThan(Version version) { - return compareTo(version) > 0; - } - - /** - * Returns whether the current {@link Version} is greater (newer) or the same as the - * given one. - * @param version must not be {@literal null}. - * @return comparison result. - */ - public boolean isGreaterThanOrEqualTo(Version version) { - return compareTo(version) >= 0; - } - - /** - * Returns whether the current {@link Version} is the same as the given one. - * @param version must not be {@literal null}. - * @return comparison result. - */ - public boolean is(Version version) { - return equals(version); - } - - /** - * Returns whether the current {@link Version} is less (older) than the given one. - * @param version must not be {@literal null}. - * @return comparison result. - */ - public boolean isLessThan(Version version) { - return compareTo(version) < 0; - } - - /** - * Returns whether the current {@link Version} is less (older) or equal to the current - * one. - * @param version must not be {@literal null}. - * @return comparison result. - */ - public boolean isLessThanOrEqualTo(Version version) { - return compareTo(version) <= 0; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Comparable#compareTo(java.lang.Object) - */ - public int compareTo(Version that) { - - if (that == null) { - return 1; - } - - if (this.major != that.major) { - return this.major - that.major; - } - - if (this.minor != that.minor) { - return this.minor - that.minor; - } - - if (this.bugfix != that.bugfix) { - return this.bugfix - that.bugfix; - } - - if (this.build != that.build) { - return this.build - that.build; - } - - return 0; - } - - public boolean isEnterprise() { - return this.enterprise; - } - - /* - * (non-Javadoc) - * - * @see java.lang.Object#toString() - */ - @Override - public String toString() { - - List digits = new ArrayList(); - digits.add(this.major); - digits.add(this.minor); - - if (this.build != 0 || this.bugfix != 0) { - digits.add(this.bugfix); - } - - if (this.build != 0) { - digits.add(this.build); - } - - return StringUtils.collectionToDelimitedString(digits, ".") + (isEnterprise() ? "+ent" : ""); - } - - @Override - public boolean equals(Object o) { - if (this == o) { - return true; - } - if (!(o instanceof Version)) { - return false; - } - Version version = (Version) o; - return this.major == version.major && this.minor == version.minor && this.bugfix == version.bugfix - && this.build == version.build && this.enterprise == version.enterprise; - } - - @Override - public int hashCode() { - return Objects.hash(this.major, this.minor, this.bugfix, this.build, this.enterprise); - } - -} diff --git a/spring-cloud-vault-config/src/test/resources/META-INF/spring.factories b/spring-cloud-vault-config/src/test/resources/META-INF/spring.factories deleted file mode 100644 index a34e0316..00000000 --- a/spring-cloud-vault-config/src/test/resources/META-INF/spring.factories +++ /dev/null @@ -1,4 +0,0 @@ -# Bootstrap Configuration -org.springframework.cloud.bootstrap.BootstrapConfiguration=\ -org.springframework.cloud.vault.config.VaultConfigAppIdCustomMechanismTests.BootstrapConfiguration,\ -org.springframework.cloud.vault.config.VaultConfigWithVaultConfigurerTests.ConfigurerBootstrapApplication diff --git a/spring-cloud-vault-config/src/test/resources/application.yml b/spring-cloud-vault-config/src/test/resources/application.yml deleted file mode 100644 index c598d962..00000000 --- a/spring-cloud-vault-config/src/test/resources/application.yml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - application.name: testVaultApp - cloud.vault.token: 00000000-0000-0000-0000-000000000000 - cloud.vault.ssl.trust-store: file:../work/keystore.jks - cloud.vault.ssl.trust-store-password: changeit diff --git a/spring-cloud-vault-config/src/test/resources/bootstrap.yml b/spring-cloud-vault-config/src/test/resources/bootstrap.yml deleted file mode 100644 index c598d962..00000000 --- a/spring-cloud-vault-config/src/test/resources/bootstrap.yml +++ /dev/null @@ -1,5 +0,0 @@ -spring: - application.name: testVaultApp - cloud.vault.token: 00000000-0000-0000-0000-000000000000 - cloud.vault.ssl.trust-store: file:../work/keystore.jks - cloud.vault.ssl.trust-store-password: changeit diff --git a/spring-cloud-vault-dependencies/pom.xml b/spring-cloud-vault-dependencies/pom.xml deleted file mode 100644 index 725fded9..00000000 --- a/spring-cloud-vault-dependencies/pom.xml +++ /dev/null @@ -1,136 +0,0 @@ - - - 4.0.0 - - - org.springframework.cloud - spring-cloud-dependencies-parent - 4.1.0-SNAPSHOT - - - - - spring-cloud-vault-dependencies - 4.1.0-SNAPSHOT - pom - - Spring Cloud Vault Dependencies - Spring Cloud Vault Dependencies - - - 3.0.2 - - - - - - - org.springframework.vault - spring-vault-core - ${spring-vault.version} - - - - org.springframework - spring-core - - - org.springframework - spring-beans - - - org.springframework - spring-web - - - - - - - org.springframework.cloud - spring-cloud-vault-config - ${project.version} - - - - org.springframework.cloud - spring-cloud-vault-config-aws - ${project.version} - - - - org.springframework.cloud - spring-cloud-vault-config-consul - ${project.version} - - - - org.springframework.cloud - spring-cloud-vault-config-databases - ${project.version} - - - - org.springframework.cloud - spring-cloud-vault-config-rabbitmq - ${project.version} - - - - - org.springframework.cloud - spring-cloud-starter-vault-config - ${project.version} - - - - - - - - - org.apache.maven.plugins - maven-deploy-plugin - 2.8.2 - - - - org.apache.maven.plugins - maven-jar-plugin - 3.2.0 - - - - org.apache.maven.plugins - maven-javadoc-plugin - 3.2.0 - - - - org.apache.maven.plugins - maven-release-plugin - 2.5.3 - - - - org.apache.maven.plugins - maven-source-plugin - 3.2.1 - - - - - - - - spring-libs-snapshot - https://repo.spring.io/libs-snapshot - - true - - - - - diff --git a/src/checkstyle/checkstyle-suppressions.xml b/src/checkstyle/checkstyle-suppressions.xml deleted file mode 100644 index 23df68af..00000000 --- a/src/checkstyle/checkstyle-suppressions.xml +++ /dev/null @@ -1,9 +0,0 @@ - - - - - - - diff --git a/src/main/resources/license.txt b/src/main/resources/license.txt deleted file mode 100644 index 964a55d1..00000000 --- a/src/main/resources/license.txt +++ /dev/null @@ -1,216 +0,0 @@ - Apache License - Version 2.0, January 2004 - https://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - https://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. - -======================================================================= - -To the extent any open source subcomponents are licensed under the EPL and/or other -similar licenses that require the source code and/or modifications to -source code to be made available (as would be noted above), you may obtain a -copy of the source code corresponding to the binaries for such open source -components and modifications thereto, if any, (the "Source Files"), by -downloading the Source Files from https://www.springsource.org/download, -or by sending a request, with your name and address to: VMware, Inc., 3401 Hillview -Avenue, Palo Alto, CA 94304, United States of America or email info@vmware.com. All -such requests should clearly specify: OPEN SOURCE FILES REQUEST, Attention General -Counsel. VMware shall mail a copy of the Source Files to you on a CD or equivalent -physical medium. This offer to obtain a copy of the Source Files is valid for three -years from the date you acquired this Software product. \ No newline at end of file diff --git a/src/main/resources/notice.txt b/src/main/resources/notice.txt deleted file mode 100644 index 30d0e12f..00000000 --- a/src/main/resources/notice.txt +++ /dev/null @@ -1,10 +0,0 @@ -Spring Cloud Vault 2.0.0.BUILD-SNAPSHOT -Copyright (c) [2016-2017] Pivotal Software, Inc. - -This product is licensed to you under the Apache License, Version 2.0 (the "License"). -You may not use this product except in compliance with the License. - -This product may include a number of subcomponents with -separate copyright notices and license terms. Your use of the source -code for the these subcomponents is subject to the terms and -conditions of the subcomponent's license, as noted in the LICENSE file. diff --git a/src/test/bash/consul.json b/src/test/bash/consul.json deleted file mode 100644 index 73936e0d..00000000 --- a/src/test/bash/consul.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "log_level": "INFO", - "server": true, - "datacenter": "dc1", - "advertise_addr": "127.0.0.1", - "acl_datacenter": "dc1", - "acl_master_token": "consul-master-token" -} \ No newline at end of file diff --git a/src/test/bash/create_certificates.sh b/src/test/bash/create_certificates.sh deleted file mode 100755 index 62811563..00000000 --- a/src/test/bash/create_certificates.sh +++ /dev/null @@ -1,123 +0,0 @@ -#!/bin/bash - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" -CA_DIR=work/ca -KEYSTORE_FILE=work/keystore.jks -CLIENT_CERT_KEYSTORE=work/client-cert.jks - -if [[ -d work/ca ]] ; then - rm -Rf ${CA_DIR} -fi - -if [[ -f ${KEYSTORE_FILE} ]] ; then - rm -Rf ${KEYSTORE_FILE} -fi - -if [[ -f ${CLIENT_CERT_KEYSTORE} ]] ; then - rm -Rf ${CLIENT_CERT_KEYSTORE} -fi - -if [ ! -x "$(which openssl)" ] ; then - echo "[ERROR] No openssl in PATH" - exit 1 -fi - -KEYTOOL=keytool - -if [ ! -x "${KEYTOOL}" ] ; then - KEYTOOL=${JAVA_HOME}/bin/keytool -fi - -if [ ! -x "${KEYTOOL}" ] ; then - echo "[ERROR] No keytool in PATH/JAVA_HOME" - exit 1 -fi - -mkdir -p ${CA_DIR}/private ${CA_DIR}/certs ${CA_DIR}/crl ${CA_DIR}/csr ${CA_DIR}/newcerts ${CA_DIR}/intermediate - -echo "[INFO] Generating CA private key" -# Less bits = less secure = faster to generate -openssl genrsa -passout pass:changeit -aes256 -out ${CA_DIR}/private/ca.key.pem 2048 - -chmod 400 ${CA_DIR}/private/ca.key.pem - -echo "[INFO] Generating CA certificate" -openssl req -config ${DIR}/openssl.cnf \ - -key ${CA_DIR}/private/ca.key.pem \ - -new -x509 -days 7300 -sha256 -extensions v3_ca \ - -out ${CA_DIR}/certs/ca.cert.pem \ - -passin pass:changeit \ - -subj "/C=NN/ST=Unknown/L=Unknown/O=spring-cloud-vault-config/CN=CA Certificate" - -echo "[INFO] Prepare CA database" -echo 1000 > ${CA_DIR}/serial -touch ${CA_DIR}/index.txt - -echo "[INFO] Generating server private key" -openssl genrsa -aes256 \ - -passout pass:changeit \ - -out ${CA_DIR}/private/localhost.key.pem 2048 - -openssl rsa -in ${CA_DIR}/private/localhost.key.pem \ - -out ${CA_DIR}/private/localhost.decrypted.key.pem \ - -passin pass:changeit - -chmod 400 ${CA_DIR}/private/localhost.key.pem -chmod 400 ${CA_DIR}/private/localhost.decrypted.key.pem - -echo "[INFO] Generating server certificate request" -openssl req -config <(cat ${DIR}/openssl.cnf \ - <(printf "\n[SAN]\nsubjectAltName=DNS:localhost,IP:127.0.0.1")) \ - -reqexts SAN \ - -key ${CA_DIR}/private/localhost.key.pem \ - -passin pass:changeit \ - -new -sha256 -out ${CA_DIR}/csr/localhost.csr.pem \ - -subj "/C=NN/ST=Unknown/L=Unknown/O=spring-cloud-vault-config/CN=localhost" - -echo "[INFO] Signing certificate request" -openssl ca -config ${DIR}/openssl.cnf \ - -extensions server_cert -days 375 -notext -md sha256 \ - -passin pass:changeit \ - -batch \ - -in ${CA_DIR}/csr/localhost.csr.pem \ - -out ${CA_DIR}/certs/localhost.cert.pem - - -echo "[INFO] Generating client auth private key" -openssl genrsa -aes256 \ - -passout pass:changeit \ - -out ${CA_DIR}/private/client.key.pem 2048 - -openssl rsa -in ${CA_DIR}/private/client.key.pem \ - -out ${CA_DIR}/private/client.decrypted.key.pem \ - -passin pass:changeit - -chmod 400 ${CA_DIR}/private/client.key.pem - -echo "[INFO] Generating client certificate request" -openssl req -config ${DIR}/openssl.cnf \ - -key ${CA_DIR}/private/client.key.pem \ - -passin pass:changeit \ - -new -sha256 -out ${CA_DIR}/csr/client.csr.pem \ - -subj "/C=NN/ST=Unknown/L=Unknown/O=spring-cloud-vault-config/CN=client" - -echo "[INFO] Signing certificate request" -openssl ca -config ${DIR}/openssl.cnf \ - -extensions usr_cert -days 375 -notext -md sha256 \ - -passin pass:changeit \ - -batch \ - -in ${CA_DIR}/csr/client.csr.pem \ - -out ${CA_DIR}/certs/client.cert.pem - -echo "[INFO] Creating PKCS12 file with client certificate" -openssl pkcs12 -export -clcerts \ - -in ${CA_DIR}/certs/client.cert.pem \ - -inkey ${CA_DIR}/private/client.decrypted.key.pem \ - -passout pass:changeit \ - -out ${CA_DIR}/client.p12 - -${KEYTOOL} -importcert -keystore ${KEYSTORE_FILE} -file ${CA_DIR}/certs/ca.cert.pem -noprompt -storepass changeit -${KEYTOOL} -importkeystore \ - -srckeystore ${CA_DIR}/client.p12 -srcstoretype PKCS12 -srcstorepass changeit\ - -destkeystore ${CLIENT_CERT_KEYSTORE} -deststoretype JKS \ - -noprompt -storepass changeit diff --git a/src/test/bash/env.sh b/src/test/bash/env.sh deleted file mode 100755 index 274302d5..00000000 --- a/src/test/bash/env.sh +++ /dev/null @@ -1,12 +0,0 @@ -#!/bin/bash - -DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" - -########################################################################### -# Vault environment settings. Source this file. # -########################################################################### - -export VAULT_TOKEN=00000000-0000-0000-0000-000000000000 -export VAULT_ADDR=https://localhost:8200 -export VAULT_SKIP_VERIFY=false -export VAULT_CAPATH=${DIR}/work/ca/certs/ca.cert.pem diff --git a/src/test/bash/install_consul.sh b/src/test/bash/install_consul.sh deleted file mode 100755 index b9469f00..00000000 --- a/src/test/bash/install_consul.sh +++ /dev/null @@ -1,46 +0,0 @@ -#!/bin/bash - -########################################################################### -# Download and Install Consul # -# This script is prepared for caching of the download directory # -########################################################################### - - -CONSUL_VER="1.7.2" -UNAME=$(uname -s | tr '[:upper:]' '[:lower:]') -CONSUL_ZIP="consul_${CONSUL_VER}_${UNAME}_amd64.zip" -IGNORE_CERTS="${IGNORE_CERTS:-no}" - -# cleanup -mkdir -p consul -mkdir -p download - -if [[ ! -f "download/${CONSUL_ZIP}" ]] ; then - cd download - # install Vault - if [[ "${IGNORE_CERTS}" == "no" ]] ; then - echo "Downloading Consul with certs verification" - wget "https://releases.hashicorp.com/consul/${CONSUL_VER}/${CONSUL_ZIP}" - else - echo "WARNING... Downloading Consul WITHOUT certs verification" - wget "https://releases.hashicorp.com/consul/${CONSUL_VER}/${CONSUL_ZIP}" --no-check-certificate - fi - - if [[ $? != 0 ]] ; then - echo "Cannot download Consul" - exit 1 - fi - cd .. -fi - -cd consul - -if [[ -f consul ]] ; then - rm consul -fi - -unzip ../download/${CONSUL_ZIP} -chmod a+x consul - -# check -./consul --version diff --git a/src/test/bash/install_rabbitmq.sh b/src/test/bash/install_rabbitmq.sh deleted file mode 100755 index 414e29a9..00000000 --- a/src/test/bash/install_rabbitmq.sh +++ /dev/null @@ -1,48 +0,0 @@ -#!/bin/bash - -########################################################################### -# Download and Install RabbitMQ # -# This script is prepared for caching of the download directory # -########################################################################### - - -RABBITMQ_VER="3.6.2" -UNAME=$(uname -s | tr '[:upper:]' '[:lower:]') - -if [[ ${UNAME} == "darwin" ]] ; then - RABBITMQ_ZIP="rabbitmq-server-mac-standalone-${RABBITMQ_VER}.tar.xz" -else - echo "Installation of RabbitMQ on ${UNAME} not supported by this script" - exit 1 -fi -IGNORE_CERTS="${IGNORE_CERTS:-no}" - -# cleanup -mkdir -p rabbitmq -mkdir -p download - -if [[ ! -f "download/${RABBITMQ_ZIP}" ]] ; then - cd download - # install Vault - if [[ "${IGNORE_CERTS}" == "no" ]] ; then - echo "Downloading RabbitMQ with certs verification" - wget "https://www.rabbitmq.com/releases/rabbitmq-server/v${RABBITMQ_VER}/${RABBITMQ_ZIP}" - else - echo "WARNING... Downloading RabbitMQ WITHOUT certs verification" - wget "https://www.rabbitmq.com/releases/rabbitmq-server/v${RABBITMQ_VER}/${RABBITMQ_ZIP}" --no-check-certificate - fi - - if [[ $? != 0 ]] ; then - echo "Cannot download RabbitMQ" - exit 1 - fi - cd .. -fi - -cd rabbitmq - -if [[ -d ebin ]] ; then - rm -Rf ../rabbitmq/* -fi - -tar xzf ../download/${RABBITMQ_ZIP} diff --git a/src/test/bash/install_vault.sh b/src/test/bash/install_vault.sh deleted file mode 100755 index 594b1c11..00000000 --- a/src/test/bash/install_vault.sh +++ /dev/null @@ -1,163 +0,0 @@ -#!/usr/bin/env bash - -########################################################################### -# Download and Install Vault # -# This script is prepared for caching of the download directory # -########################################################################### - -set -o errexit - -EDITION="${EDITION:-oss}" -VAULT_OSS="${VAULT_OSS:-1.11.0}" -VAULT_ENT="${VAULT_ENT:-1.11.0}" -UNAME=$(uname -s | tr '[:upper:]' '[:lower:]') -VERBOSE=false -VAULT_DIRECTORY=vault -DOWNLOAD_DIRECTORY=download -PLATFORM=amd64 -readonly script_name="$(basename "${BASH_SOURCE[0]}")" - -function say() { - echo "$@" -} - -function verbose() { - if [[ ${VERBOSE} == true ]]; then - echo "$@" - fi -} - -function initialize() { - # cleanup - mkdir -p ${VAULT_DIRECTORY} - mkdir -p ${DOWNLOAD_DIRECTORY} -} - -function usage() { - cat <. -countryName = Country Name (2 letter code) -stateOrProvinceName = State or Province Name -localityName = Locality Name -0.organizationName = Organization Name -organizationalUnitName = Organizational Unit Name -commonName = Common Name -emailAddress = Email Address - -# Optionally, specify some defaults. -countryName_default = NN -stateOrProvinceName_default = Vault Test -localityName_default = -0.organizationName_default = spring-cloud-vault-config -#organizationalUnitName_default = -#emailAddress_default = info@spring-cloud-vault-config.dummy - -[ v3_ca ] -# Extensions for a typical CA (`man x509v3_config`). -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always,issuer -basicConstraints = critical, CA:true -keyUsage = critical, digitalSignature, cRLSign, keyCertSign - -[ v3_intermediate_ca ] -# Extensions for a typical intermediate CA (`man x509v3_config`). -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid:always,issuer -basicConstraints = critical, CA:true, pathlen:0 -keyUsage = critical, digitalSignature, cRLSign, keyCertSign - -[ usr_cert ] -# Extensions for client certificates (`man x509v3_config`). -basicConstraints = CA:FALSE -nsCertType = client, email -nsComment = "OpenSSL Generated Client Certificate" -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid,issuer -keyUsage = critical, nonRepudiation, digitalSignature, keyEncipherment -extendedKeyUsage = clientAuth, emailProtection - -[ server_cert ] -# Extensions for server certificates (`man x509v3_config`). -basicConstraints = CA:FALSE -nsCertType = server -nsComment = "OpenSSL Generated Server Certificate" -subjectKeyIdentifier = hash -authorityKeyIdentifier = keyid,issuer:always -keyUsage = critical, digitalSignature, keyEncipherment -extendedKeyUsage = serverAuth diff --git a/src/test/bash/vault.conf b/src/test/bash/vault.conf deleted file mode 100644 index 8f61a021..00000000 --- a/src/test/bash/vault.conf +++ /dev/null @@ -1,12 +0,0 @@ -backend "inmem" { -} - -listener "tcp" { - address = "0.0.0.0:8200" - tls_cert_file = "work/ca/certs/localhost.cert.pem" - tls_key_file = "work/ca/private/localhost.decrypted.key.pem" -} - -plugin_directory = "plugins" -api_addr = "https://127.0.0.1:8200" -disable_mlock = true diff --git a/supplemental-ui/partials/nav-search.hbs b/supplemental-ui/partials/nav-search.hbs new file mode 100644 index 00000000..5e379552 --- /dev/null +++ b/supplemental-ui/partials/nav-search.hbs @@ -0,0 +1,11 @@ +{{#if env.ALGOLIA_API_KEY}} +

+{{/if}} diff --git a/supplemental-ui/partials/search.hbs b/supplemental-ui/partials/search.hbs new file mode 100644 index 00000000..384e505f --- /dev/null +++ b/supplemental-ui/partials/search.hbs @@ -0,0 +1,27 @@ + +{{#if env.ALGOLIA_API_KEY}} + + + + + + + + +{{/if}} diff --git a/work/ca/certs/ca.cert.pem b/work/ca/certs/ca.cert.pem new file mode 100644 index 00000000..7e025d7a --- /dev/null +++ b/work/ca/certs/ca.cert.pem @@ -0,0 +1,23 @@ +-----BEGIN CERTIFICATE----- +MIIDwjCCAqqgAwIBAgIJAP2KM+OC8n/PMA0GCSqGSIb3DQEBCwUAMG4xCzAJBgNV +BAYTAk5OMRAwDgYDVQQIDAdVbmtub3duMRAwDgYDVQQHDAdVbmtub3duMSIwIAYD +VQQKDBlzcHJpbmctY2xvdWQtdmF1bHQtY29uZmlnMRcwFQYDVQQDDA5DQSBDZXJ0 +aWZpY2F0ZTAeFw0yMjEwMTcxODUxNDBaFw00MjEwMTIxODUxNDBaMG4xCzAJBgNV +BAYTAk5OMRAwDgYDVQQIDAdVbmtub3duMRAwDgYDVQQHDAdVbmtub3duMSIwIAYD +VQQKDBlzcHJpbmctY2xvdWQtdmF1bHQtY29uZmlnMRcwFQYDVQQDDA5DQSBDZXJ0 +aWZpY2F0ZTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMKyMiNupr08 +3SxUw5qCf5aOSoh1viyj2xSPo2QNC3f2J593jDfSF5YEDAFUTwJeKDmUU37WQSQz +qom3XYnK7jscMxbaDigGl0VygyFvJnzRSVcUvzSvR4cFTgYPU4DM20ShR2M6bweS +ngGG6B/eQ734+bYzDWU6ysLtgxlD746+15Zj+Zh9CpjvnHaMI+IcGxKTPD2onLiu +TLeFWJYAqI/j5AxAI+Bpp7yzhCHGoPj7A168NxiEq4DWZb1S2ALu5FY2Eom99RhJ +HHfZUWDw9RPCjgQOoJ8vTlW980hjZ3CBazBYCGKvO+X0z571Z95w7Y6oShweg1iN +iyYSOyiUpUUCAwEAAaNjMGEwHQYDVR0OBBYEFNtS1jj0x2PMGQ9i3lSET7nc0LxT +MB8GA1UdIwQYMBaAFNtS1jj0x2PMGQ9i3lSET7nc0LxTMA8GA1UdEwEB/wQFMAMB +Af8wDgYDVR0PAQH/BAQDAgGGMA0GCSqGSIb3DQEBCwUAA4IBAQCqR44RATyXsjYs +fDPyBbsCl6Wo9vLh0HPVX2vMIJRe6W5kL3tB5eYMDO8WMOuYO0flrEGFhKw5oKgm +Q6rVtuPhmzdgm37kVJwuwOU+bWiC1CyhYAhhijxUc/E1lG0hh1HZ1/Gvubl+SPlx +oxwsEAdG6ZGvGW++DomBamJOqj0pxpcq4ETnIWiYp3bo+5GoAemByXs3gZGmjCvJ +uMpBQNM+RNRxVfku3gaAEhOvLJF98qNpsMyyz3+l8dmqRCsj1yGBWS7cU8VX/npd +FBkBzr7EvIwiflC7uMpKCSPEiUIJ+kX3Z77T9aCFE/FmjT663MO4tTK82hfGiPSJ +rhbikzJT +-----END CERTIFICATE----- diff --git a/work/ca/certs/client.cert.pem b/work/ca/certs/client.cert.pem new file mode 100644 index 00000000..2260ceb6 --- /dev/null +++ b/work/ca/certs/client.cert.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEBDCCAuygAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwbjELMAkGA1UEBhMCTk4x +EDAOBgNVBAgMB1Vua25vd24xEDAOBgNVBAcMB1Vua25vd24xIjAgBgNVBAoMGXNw +cmluZy1jbG91ZC12YXVsdC1jb25maWcxFzAVBgNVBAMMDkNBIENlcnRpZmljYXRl +MB4XDTIyMTAxNzE4NTE0MFoXDTIzMTAyNzE4NTE0MFowVDELMAkGA1UEBhMCTk4x +EDAOBgNVBAgMB1Vua25vd24xIjAgBgNVBAoMGXNwcmluZy1jbG91ZC12YXVsdC1j +b25maWcxDzANBgNVBAMMBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAN6VLhwEShLHysgxGikLlmY1PABBqy21BLxrVTcEH+tx5Ubn7s+FMsYs +JRBhY/eqWG+cRkXuuefIzspGq+GXLjucJOZTRlqEmccdofhEMwYrWjKI9aEPbfs8 +4R40uYEyR0vi0xV3p4/xNk2KiMNqPC38yF0gBgqsF7/wDO4hM3D38zcLPK9MDy86 +GoLZWrZAg7pSYJfystaQNWg1BaPK5lnxHIPbVzfMCn/Osv6g3Zr4+vrdzO3MgkxS +SKwvubf3WSPPiAsCbYp9GGRVGPikRtT57+K/tUwPPhgGRZ310wh7YDf/iVQM5oEJ +ZDVUzE+2Xp3A45N+qhTpaSDpvU6cojUCAwEAAaOBxTCBwjAJBgNVHRMEAjAAMBEG +CWCGSAGG+EIBAQQEAwIFoDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0 +ZWQgQ2xpZW50IENlcnRpZmljYXRlMB0GA1UdDgQWBBQFi19XayVG19aEqvUNxKch +/1AprzAfBgNVHSMEGDAWgBTbUtY49MdjzBkPYt5UhE+53NC8UzAOBgNVHQ8BAf8E +BAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEB +CwUAA4IBAQCU2A1ILWxLbH/2cI2NNT4vC0ZX4NFs3J9EJVHR4gn77IjJINqHMMw/ +bWJej//rgXU7UBO2BbDXcYTMavpBBIWCYWFgrfu0Z+NjAIMaejGdjAr8eElLHrkH +xi1ROqeb0a2MxQmVEPJBJQQPQZNchFyhnrlJIOeII/mYzaiMLnM70L5X5j3AUy7Q +NfwnNUwct6SbmZHfDq5DNuuPy5IGQ3hIqg6ADraywcR1vxrnPH5ZnrC2lg7yuX+n +TYHDCyOns2iNScC7rGGn05AL0NNGSBzivoIDGElyU2sRuv6qxDZsj5kyUFb2AFOA +MnBMBrDiahm1evejtdRgkUqqMjoMW2au +-----END CERTIFICATE----- diff --git a/work/ca/certs/localhost.cert.pem b/work/ca/certs/localhost.cert.pem new file mode 100644 index 00000000..db22fd72 --- /dev/null +++ b/work/ca/certs/localhost.cert.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEnTCCA4WgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwbjELMAkGA1UEBhMCTk4x +EDAOBgNVBAgMB1Vua25vd24xEDAOBgNVBAcMB1Vua25vd24xIjAgBgNVBAoMGXNw +cmluZy1jbG91ZC12YXVsdC1jb25maWcxFzAVBgNVBAMMDkNBIENlcnRpZmljYXRl +MB4XDTIyMTAxNzE4NTE0MFoXDTIzMTAyNzE4NTE0MFowVzELMAkGA1UEBhMCTk4x +EDAOBgNVBAgMB1Vua25vd24xIjAgBgNVBAoMGXNwcmluZy1jbG91ZC12YXVsdC1j +b25maWcxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMndFRdQmkWqkvR1mWoE+p4C8Fwmn98v6SU0KRdCu7XIkV5SQMJD +suhtDT6szE5+nj1IY98TplxBfhqx/LvYwRr6MNeD4yQTf5xFdzVdtQh57iC4Obf1 +J9bwuOkO6UW3c/iqBF+uxRfnpnoRfruMzygxav0Hm04cDHUOCXX4KppDRQfx5eHg ++3mP01/zYi1XGg+VwEPG1D8niIvBrW1D2IZfiiY+tif7jiuNZR/kvikaoOvfMnIW +lsWSzCp1JAORpV8KscDokKqsP2dxEWDCmqNHfQUpqcaDcv1AJ+oPyzrrgNK5EBtY +ustR5d+S2OTTaD95hvY8Iy3NOXJ3m+3yU9cCAwEAAaOCAVowggFWMAkGA1UdEwQC +MAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdl +bmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFMAYj7jC9Q8yAQDX +HWLOjCrzlM5UMIGgBgNVHSMEgZgwgZWAFNtS1jj0x2PMGQ9i3lSET7nc0LxToXKk +cDBuMQswCQYDVQQGEwJOTjEQMA4GA1UECAwHVW5rbm93bjEQMA4GA1UEBwwHVW5r +bm93bjEiMCAGA1UECgwZc3ByaW5nLWNsb3VkLXZhdWx0LWNvbmZpZzEXMBUGA1UE +AwwOQ0EgQ2VydGlmaWNhdGWCCQD9ijPjgvJ/zzAOBgNVHQ8BAf8EBAMCBaAwEwYD +VR0lBAwwCgYIKwYBBQUHAwEwGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMA0G +CSqGSIb3DQEBCwUAA4IBAQBCaw4utdEDfKB7q+AIJ4tu5giIIEtdtb9gmWJNXeWO +JOYfDrU0m8rdQYtrGfzJc/yTd4PaRMn/MzCuMGw74vJj0XDvFLTjJaEsU26ZHeVe +VRe7e9pngPvMHS9HLZz0IaDZOx/6V2N6ASwB+e0IEpIdaHOCgS5M1FXhaHh8NwIw +kF8XwU0sikbXZIBTOc/as5ecoIj7ijIkwjQjDCNVuWaT0OcDOp2Y6bZyJZZfcHE5 +wLajBOtE/uV6ecIZ8zAe7nc1746e5CnZPYQbj//WS31y4dCwQlczkLcFbOJ71ewp +n3KYhtsmTjRUg7n9NJkB6UEb0bia5RVjNBV5md5qNSW/ +-----END CERTIFICATE----- diff --git a/work/ca/client.p12 b/work/ca/client.p12 new file mode 100644 index 00000000..698e68ee Binary files /dev/null and b/work/ca/client.p12 differ diff --git a/work/ca/csr/client.csr.pem b/work/ca/csr/client.csr.pem new file mode 100644 index 00000000..53db097b --- /dev/null +++ b/work/ca/csr/client.csr.pem @@ -0,0 +1,17 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIICqzCCAZMCAQAwZjELMAkGA1UEBhMCTk4xEDAOBgNVBAgMB1Vua25vd24xEDAO +BgNVBAcMB1Vua25vd24xIjAgBgNVBAoMGXNwcmluZy1jbG91ZC12YXVsdC1jb25m +aWcxDzANBgNVBAMMBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC +ggEBAN6VLhwEShLHysgxGikLlmY1PABBqy21BLxrVTcEH+tx5Ubn7s+FMsYsJRBh +Y/eqWG+cRkXuuefIzspGq+GXLjucJOZTRlqEmccdofhEMwYrWjKI9aEPbfs84R40 +uYEyR0vi0xV3p4/xNk2KiMNqPC38yF0gBgqsF7/wDO4hM3D38zcLPK9MDy86GoLZ +WrZAg7pSYJfystaQNWg1BaPK5lnxHIPbVzfMCn/Osv6g3Zr4+vrdzO3MgkxSSKwv +ubf3WSPPiAsCbYp9GGRVGPikRtT57+K/tUwPPhgGRZ310wh7YDf/iVQM5oEJZDVU +zE+2Xp3A45N+qhTpaSDpvU6cojUCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IBAQB6 +XmVr8vEusKlVBYlV+f4ZOdnnOM6bdzzSFF/9hOYh+Y+X7kSnoNDGdCpLadFXgwXJ +7TdHR6OwO76pxSHWtfdla+x3YYkdqq1uvN0Nwy2AATRpNPsGgoQlOujLvD3rbX00 ++Gxatkj+KIJcJQY9T0Q31WWhSsvAq1+DlYUJyQUgIia1k/FVAMQjM4dMD8a1hRu2 +nFKJpPrapwlkWDxAYuI5pg83kMcWdPVBRBGMsuUywZRSdF6wgsQGvhTXILYjrWyd +b9T06HGcua+sFdueI0bBVGWuexOqsxo2vsP1z/wvTQb1EHeLQaoJ4zulJghQ0qkO +78SbuqxyXD9wEKaR9Sva +-----END CERTIFICATE REQUEST----- diff --git a/work/ca/csr/localhost.csr.pem b/work/ca/csr/localhost.csr.pem new file mode 100644 index 00000000..c87c3a86 --- /dev/null +++ b/work/ca/csr/localhost.csr.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIC2zCCAcMCAQAwaTELMAkGA1UEBhMCTk4xEDAOBgNVBAgMB1Vua25vd24xEDAO +BgNVBAcMB1Vua25vd24xIjAgBgNVBAoMGXNwcmluZy1jbG91ZC12YXVsdC1jb25m +aWcxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAMndFRdQmkWqkvR1mWoE+p4C8Fwmn98v6SU0KRdCu7XIkV5SQMJDsuht +DT6szE5+nj1IY98TplxBfhqx/LvYwRr6MNeD4yQTf5xFdzVdtQh57iC4Obf1J9bw +uOkO6UW3c/iqBF+uxRfnpnoRfruMzygxav0Hm04cDHUOCXX4KppDRQfx5eHg+3mP +01/zYi1XGg+VwEPG1D8niIvBrW1D2IZfiiY+tif7jiuNZR/kvikaoOvfMnIWlsWS +zCp1JAORpV8KscDokKqsP2dxEWDCmqNHfQUpqcaDcv1AJ+oPyzrrgNK5EBtYustR +5d+S2OTTaD95hvY8Iy3NOXJ3m+3yU9cCAwEAAaAtMCsGCSqGSIb3DQEJDjEeMBww +GgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMA0GCSqGSIb3DQEBCwUAA4IBAQDE +WnU7Y0ScdMPth5E2S9kpZrTHWc0ga2MbUx0QRQrI8qtzSmOClRxIC2T9pmTFVziy +4+9z3AMy3WfGy0fhHEzQFm3UTBitsIL2sWgQ732JkxnR8cyg4YDr2DJpxPtxFY7L +zKdDBnP6DY/qz/Za24eEKAlr5bjx2DlysG0HX4KYtBQDb9H41aYv8ylagGp0AyaM +96MyeJpV4BL0yZsykIHXZYGIP/J4YvEWD0PkoM7/FtKCIw7DK1K4hjHtohTLHEO/ +uQf2j6LN+8erhZ6hBuCZb+nUCfQWf5/Etes7FSfgOPwnpHF72yhC8Mvw715sSeeF +Nz6iyGkY21A8A6MtVyMF +-----END CERTIFICATE REQUEST----- diff --git a/work/ca/index.txt b/work/ca/index.txt new file mode 100644 index 00000000..d0fc3fe8 --- /dev/null +++ b/work/ca/index.txt @@ -0,0 +1,2 @@ +V 231027185140Z 1000 unknown /C=NN/ST=Unknown/O=spring-cloud-vault-config/CN=localhost +V 231027185140Z 1001 unknown /C=NN/ST=Unknown/O=spring-cloud-vault-config/CN=client diff --git a/work/ca/index.txt.attr b/work/ca/index.txt.attr new file mode 100644 index 00000000..8f7e63a3 --- /dev/null +++ b/work/ca/index.txt.attr @@ -0,0 +1 @@ +unique_subject = yes diff --git a/work/ca/index.txt.attr.old b/work/ca/index.txt.attr.old new file mode 100644 index 00000000..8f7e63a3 --- /dev/null +++ b/work/ca/index.txt.attr.old @@ -0,0 +1 @@ +unique_subject = yes diff --git a/work/ca/index.txt.old b/work/ca/index.txt.old new file mode 100644 index 00000000..3d8cd266 --- /dev/null +++ b/work/ca/index.txt.old @@ -0,0 +1 @@ +V 231027185140Z 1000 unknown /C=NN/ST=Unknown/O=spring-cloud-vault-config/CN=localhost diff --git a/work/ca/newcerts/1000.pem b/work/ca/newcerts/1000.pem new file mode 100644 index 00000000..db22fd72 --- /dev/null +++ b/work/ca/newcerts/1000.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEnTCCA4WgAwIBAgICEAAwDQYJKoZIhvcNAQELBQAwbjELMAkGA1UEBhMCTk4x +EDAOBgNVBAgMB1Vua25vd24xEDAOBgNVBAcMB1Vua25vd24xIjAgBgNVBAoMGXNw +cmluZy1jbG91ZC12YXVsdC1jb25maWcxFzAVBgNVBAMMDkNBIENlcnRpZmljYXRl +MB4XDTIyMTAxNzE4NTE0MFoXDTIzMTAyNzE4NTE0MFowVzELMAkGA1UEBhMCTk4x +EDAOBgNVBAgMB1Vua25vd24xIjAgBgNVBAoMGXNwcmluZy1jbG91ZC12YXVsdC1j +b25maWcxEjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEP +ADCCAQoCggEBAMndFRdQmkWqkvR1mWoE+p4C8Fwmn98v6SU0KRdCu7XIkV5SQMJD +suhtDT6szE5+nj1IY98TplxBfhqx/LvYwRr6MNeD4yQTf5xFdzVdtQh57iC4Obf1 +J9bwuOkO6UW3c/iqBF+uxRfnpnoRfruMzygxav0Hm04cDHUOCXX4KppDRQfx5eHg ++3mP01/zYi1XGg+VwEPG1D8niIvBrW1D2IZfiiY+tif7jiuNZR/kvikaoOvfMnIW +lsWSzCp1JAORpV8KscDokKqsP2dxEWDCmqNHfQUpqcaDcv1AJ+oPyzrrgNK5EBtY +ustR5d+S2OTTaD95hvY8Iy3NOXJ3m+3yU9cCAwEAAaOCAVowggFWMAkGA1UdEwQC +MAAwEQYJYIZIAYb4QgEBBAQDAgZAMDMGCWCGSAGG+EIBDQQmFiRPcGVuU1NMIEdl +bmVyYXRlZCBTZXJ2ZXIgQ2VydGlmaWNhdGUwHQYDVR0OBBYEFMAYj7jC9Q8yAQDX +HWLOjCrzlM5UMIGgBgNVHSMEgZgwgZWAFNtS1jj0x2PMGQ9i3lSET7nc0LxToXKk +cDBuMQswCQYDVQQGEwJOTjEQMA4GA1UECAwHVW5rbm93bjEQMA4GA1UEBwwHVW5r +bm93bjEiMCAGA1UECgwZc3ByaW5nLWNsb3VkLXZhdWx0LWNvbmZpZzEXMBUGA1UE +AwwOQ0EgQ2VydGlmaWNhdGWCCQD9ijPjgvJ/zzAOBgNVHQ8BAf8EBAMCBaAwEwYD +VR0lBAwwCgYIKwYBBQUHAwEwGgYDVR0RBBMwEYIJbG9jYWxob3N0hwR/AAABMA0G +CSqGSIb3DQEBCwUAA4IBAQBCaw4utdEDfKB7q+AIJ4tu5giIIEtdtb9gmWJNXeWO +JOYfDrU0m8rdQYtrGfzJc/yTd4PaRMn/MzCuMGw74vJj0XDvFLTjJaEsU26ZHeVe +VRe7e9pngPvMHS9HLZz0IaDZOx/6V2N6ASwB+e0IEpIdaHOCgS5M1FXhaHh8NwIw +kF8XwU0sikbXZIBTOc/as5ecoIj7ijIkwjQjDCNVuWaT0OcDOp2Y6bZyJZZfcHE5 +wLajBOtE/uV6ecIZ8zAe7nc1746e5CnZPYQbj//WS31y4dCwQlczkLcFbOJ71ewp +n3KYhtsmTjRUg7n9NJkB6UEb0bia5RVjNBV5md5qNSW/ +-----END CERTIFICATE----- diff --git a/work/ca/newcerts/1001.pem b/work/ca/newcerts/1001.pem new file mode 100644 index 00000000..2260ceb6 --- /dev/null +++ b/work/ca/newcerts/1001.pem @@ -0,0 +1,24 @@ +-----BEGIN CERTIFICATE----- +MIIEBDCCAuygAwIBAgICEAEwDQYJKoZIhvcNAQELBQAwbjELMAkGA1UEBhMCTk4x +EDAOBgNVBAgMB1Vua25vd24xEDAOBgNVBAcMB1Vua25vd24xIjAgBgNVBAoMGXNw +cmluZy1jbG91ZC12YXVsdC1jb25maWcxFzAVBgNVBAMMDkNBIENlcnRpZmljYXRl +MB4XDTIyMTAxNzE4NTE0MFoXDTIzMTAyNzE4NTE0MFowVDELMAkGA1UEBhMCTk4x +EDAOBgNVBAgMB1Vua25vd24xIjAgBgNVBAoMGXNwcmluZy1jbG91ZC12YXVsdC1j +b25maWcxDzANBgNVBAMMBmNsaWVudDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAN6VLhwEShLHysgxGikLlmY1PABBqy21BLxrVTcEH+tx5Ubn7s+FMsYs +JRBhY/eqWG+cRkXuuefIzspGq+GXLjucJOZTRlqEmccdofhEMwYrWjKI9aEPbfs8 +4R40uYEyR0vi0xV3p4/xNk2KiMNqPC38yF0gBgqsF7/wDO4hM3D38zcLPK9MDy86 +GoLZWrZAg7pSYJfystaQNWg1BaPK5lnxHIPbVzfMCn/Osv6g3Zr4+vrdzO3MgkxS +SKwvubf3WSPPiAsCbYp9GGRVGPikRtT57+K/tUwPPhgGRZ310wh7YDf/iVQM5oEJ +ZDVUzE+2Xp3A45N+qhTpaSDpvU6cojUCAwEAAaOBxTCBwjAJBgNVHRMEAjAAMBEG +CWCGSAGG+EIBAQQEAwIFoDAzBglghkgBhvhCAQ0EJhYkT3BlblNTTCBHZW5lcmF0 +ZWQgQ2xpZW50IENlcnRpZmljYXRlMB0GA1UdDgQWBBQFi19XayVG19aEqvUNxKch +/1AprzAfBgNVHSMEGDAWgBTbUtY49MdjzBkPYt5UhE+53NC8UzAOBgNVHQ8BAf8E +BAMCBeAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMA0GCSqGSIb3DQEB +CwUAA4IBAQCU2A1ILWxLbH/2cI2NNT4vC0ZX4NFs3J9EJVHR4gn77IjJINqHMMw/ +bWJej//rgXU7UBO2BbDXcYTMavpBBIWCYWFgrfu0Z+NjAIMaejGdjAr8eElLHrkH +xi1ROqeb0a2MxQmVEPJBJQQPQZNchFyhnrlJIOeII/mYzaiMLnM70L5X5j3AUy7Q +NfwnNUwct6SbmZHfDq5DNuuPy5IGQ3hIqg6ADraywcR1vxrnPH5ZnrC2lg7yuX+n +TYHDCyOns2iNScC7rGGn05AL0NNGSBzivoIDGElyU2sRuv6qxDZsj5kyUFb2AFOA +MnBMBrDiahm1evejtdRgkUqqMjoMW2au +-----END CERTIFICATE----- diff --git a/work/ca/private/ca.key.pem b/work/ca/private/ca.key.pem new file mode 100644 index 00000000..a1a47101 --- /dev/null +++ b/work/ca/private/ca.key.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,66DB3AE092B762C66E0F08B573834BC6 + +HZiQMDqinYMyjQ3LMgpq54CNOcvotVQVArLnf8E4/BPydt1K1yGxKCh3SlotLAe/ +WQODDlZIu4nTMtPx6C4+ciDR7HM/iqrZIhImgX1GOfaKMSWVC22HXgl2XiLlxDj7 +SHtEQjYPTGx68sj8ujTTRq8F9A6Ds/Wx8dONPOOMdHbS6BoAqykRY5KrkLHk0Qa7 +pwZl5ug+xj5D59u2ww7mwz+4v4p8iif7bHoHPRf8fFoS3St6DEkZJOD69G/fV06c +ovo0rwQKRiCEt3J4RWI0PVlmc8DiegNKuopVRtXe1OGnHaCd4cMOEkf0KvG53/JE +3XYeq5C3F2e5by89gc3qkqnMP2Czvv3kxYvhp2GtjNhgRFh/1kY7YAONO9rs4DnY +0GTmDG36UU61e3kMCc4NXmcyotjuIePSuvW/KHP6l8j5y7RXrYP7hRPBiYNFhE8n +96ERylgFB/uIpZD2LaqoJSIO0rhWN/zn93ooxWEl0Ub/OaMRdIvZ1rFWfAS4sIzD +sRs1fUXaH6y+ezz9p7ShSWAtc5FidIm4vVOt8UU2ITWunteY9gm5jm1b68pz7dD/ +oDXudc1KAM0gTOwmvSoD8rukrcOtkwDWko1skq/mO/mmvuHf/OETvXdF2bc0iQRe +z8L3niX50Kj7MBfV3S92quaPUT1b6MGba45WFVRrVlioJXrHiC3DMts67JwIQRez +SEQLw1+KF1phvNHF1HkirhK0JzWhGKo48hFL1si8AIB6/6ykwDsFLA53MzBHn2Mw +HMAjox2u/iaNjEGl76rYOcNpOq7HbJSQgmJS+Pp7HTG51Z8lrtZJ7mrBDXVMcgYN +MIIw8R4UKjw/1Pg393iJ9ZyDWYdnMXW/ozA5MEk7BKrR+dIO7VocoykYXtxTkwJs +LPBCUKrhjdLCcb53p21pB95IGEKjA+2DQrj1yHClrlZv+2sR+/ZxpUypqQza9+Ly +maqpCotGlOveDGjy3u66bPbIA03WIxNxIJqiaArx23DRi2CVH4amnqjJCS61TBov +HJlAL/pbi31OwhH1LgEbqYcqTve2Hsng1O+Hm8A8QGq/XQwFFqWJ9edtfr/EV8TW +wRn+Tv0ZIRrEhngdeeA2dY/8HBlEvYN6OquX9qUrgZMsyklV4nCtuE1RSRECqALZ +Gv5d5ePiQYbnRHIOFen00bFR1BrxTQaTV3arlTXdeDu8rKISwsxZlxKOLu14KizJ +wvnJ5pcznE613RhQREVksRU30B0lp7blCJRNBCbRZF6rusvAqlyjxJ7bQqkrCvMg +Z8REL13cHl+ErXDFgwbXrWCOzcFrysksw3jbiW9lEvdrRejonQj3Lx5vryvpke0C +c6mq2jzZJushUmYI5yZ3WM1+nqe+x3PW4VIlBOfQBjyrSvlli7vGaF1+jLhlldNQ +fRqCj/NZP4c0kE42RLstURrH9ianXJ5iatf+qA9zC1md2xsfNgloJZI2MYoWaFbl +6jEleJG/+BOVUlr1C3P8RoU1ppk0fx52VKGQgvqZFOuofAQZsC7JZI0wPfC7oZiN +ItmRqHUABFMeZ94OCLBC6GYedBJnRTw7VWanbRdeaZKvboTZSjq6dou/Ci9m94o7 +-----END RSA PRIVATE KEY----- diff --git a/work/ca/private/client.decrypted.key.pem b/work/ca/private/client.decrypted.key.pem new file mode 100644 index 00000000..41c3df78 --- /dev/null +++ b/work/ca/private/client.decrypted.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEA3pUuHARKEsfKyDEaKQuWZjU8AEGrLbUEvGtVNwQf63HlRufu +z4UyxiwlEGFj96pYb5xGRe6558jOykar4ZcuO5wk5lNGWoSZxx2h+EQzBitaMoj1 +oQ9t+zzhHjS5gTJHS+LTFXenj/E2TYqIw2o8LfzIXSAGCqwXv/AM7iEzcPfzNws8 +r0wPLzoagtlatkCDulJgl/Ky1pA1aDUFo8rmWfEcg9tXN8wKf86y/qDdmvj6+t3M +7cyCTFJIrC+5t/dZI8+ICwJtin0YZFUY+KRG1Pnv4r+1TA8+GAZFnfXTCHtgN/+J +VAzmgQlkNVTMT7ZencDjk36qFOlpIOm9TpyiNQIDAQABAoIBAQCOyy21k5rhyYLy +Q24A/woRr/06PObQf9z18/XLQb4okf0BLDIst8sHD7MHezNi48mwcJU0sB5b8JuZ +cRU7uH1UiKuzh6EO2Rq+fug2GaqSPqWy3eKW3Qs1rqzNcA3CMLtEl9PLZeP9mEW6 +ITH0C+dnqU/xTmYR2q2x2RKygmI6CeT6YoUzElLyA6G1XnNO3ufXNN/dlxIDsxmR +lhX5L4M1g76Ly0rwI04lM44VUVrNvbWHB+PU2rr+6Nd7ts69N3vtWkvdz+FGCTHx +YbbveNyQlXni7ydlfsfxJuO2Ot+9xq8KqL3y1KLY2ZfQQ2YOU5t/rKjlNC7LLFY/ +kGYCNTxRAoGBAP506dcWtB7vuq5mmc30MxOEc3D1sJcrCmo8bp1NGs48tHwM+SRt +J16caXiGckfkRtlbXZomsCmJAzK/WBcQQTj3vhRdzIsgXEKD8kzvqpvDKEwXGJr6 +jVu0No5SxsjTTM0OsFLGJ0q66cuMVzFmSXTAKK+zXPkKyxY/yPUObM67AoGBAN/u +xus/v25C0ZlnxgMX0aEUNRAC9K8/QYSC/nO9zLvZfILA6bUlNRwQ+nudbMN1a43B +ticO61gxWQhOnY6cRnLzgFWxxDkh8rTVuGeJjIHHQSX5C4GOoFHjtXrcbIBBLKVS +hSgdNoHNTjuiqbw4NIUDnMcqdTTUqd8q1fojn1vPAoGAMsP6fzn9V4q2cOLxXoCQ +zB0JtwidYZtpqYZC/0kJxwmfbHxeHGFWkG6eMDiKhkNJy0WKKB392VuHctFv7rIE +gSwUFRYdn8gl//M5HRZXsFnAKWYWN50zJI+QrtZe6GQXl3WNwgXcgvFFgaGPJ8Dj +eNJ5i4w6SUlY+ShinFlzZc8CgYB+E4+HL5L130Tm29hOMYDi8d+WLjPY3wJiOuZL +/9ZfBOnnK/no9RPbw2tjYZS0z01IuIF3qBy0wMPhu3FVs4KugY4FsVpK2GQvkAyM +rpKfFrIFURw7SzPUJyIsFCI6a3dZdQZnOVtQ5WhghwqNYA+hvBDuyWbH4dvqO9HR +TXERXQKBgAPUcUXGVB/C0Gd/vSlgjbCW+wnF7je0pUvA7pTdyK29S6uadtamJOoW +fdEQVoSnRohmbdhasrS4QdjZ2Ik60uDYtwklT7OufaOmMQa+1Gnca7MFD/KBJm8C +rY2Bn2Vzdqij1Mskv4UvQYl7Ec+dH12ySA9lSOoznXxVXIMCjgWw +-----END RSA PRIVATE KEY----- diff --git a/work/ca/private/client.key.pem b/work/ca/private/client.key.pem new file mode 100644 index 00000000..a40d3f98 --- /dev/null +++ b/work/ca/private/client.key.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,5EB5DA175B79FE56D01577E639053DE9 + +5BTSTfsBF74elg2QkINCuxsdzSQd6vq+AQTYslylUJulW0oiBln/mHAkT/YzWbpF +9SlDkju++l4GrZLfEMW3XX79sBedNRi1vNbqmldYKoMkpGf3XfNxb+O4sXrbePxh +VukNeI2STipmQ1PWNXT6UOKdWpuEKC0BIj+/+yek3DCmfaX+0QSCVRELwivURHe2 ++TraUJum2voyzlVVdau9Le57qtwZtC7LSsDrFPssQzA859rIcHrcwxs0OnTm9FvZ +uP0Lea+dy5MPyfkUWrcCk5ogD7COgOp6MMw/OrABU81w+qZHlYoqPa4Osx9pYV7Q +/dEU1n529r6gTCMHIacbOL5o8Iif6t5JHDyzAR/crWAcPhoLB0dITuWDHTfjkP+y +SDjouMykdwitjc+nZvjJx40SxChNqa1k5V2XFI0fJCvsSzXLJP+ThKRH9mWB0APF +vgHRWv70F4bBOfkQkO8wWum4freP5ZCnKQ9XN1/kDnALdBaRLi4UeFhL4Oa2KbdO +rs0vHlhwKv1FenSEgZ8erGhF6b7VLZKnBBDY7hhwpFjje+xHhex3VTHZIxNXjkFT +UthWYo3H39MKNs6l6ONxCFkXgrB40FCeExuFk5tN+lOi7h3W2BUQjoiUngkrKG25 +FBrfrJ80Q3QoQAQjeE048mV2K8g8I/gfe1PR2tFiiSpX8VvMxuo8zoQq/66EFrNk +HozHvr3GXKEm5EcegqzM5Nxos6RHJkwPxBXC8FI/9vrAkjQ/q/XVWiCrTnlpAmTa +/XYUvb0iGK9bhh+hbiZx4R7Tp6HXZ8JZrTD7E2NMd8yarWP5HISamNRRLbqBzSda +8bnvKvsOx/Xsknfi6OLdJ2s3o2cOcdsgmjVNYRshCDAr/rpr40MGget1V7UjT4V7 +BIbI/GFI4jcualQdk+fW3kXOfVNNzfWZ3awrsqt+r2/PDyQ+3UoqPWbIA3CieVVL +teTvDn+YKfGmC8k93aO7V/rVbvQgzatYd09xbjO0vdogJ4FJ1l+/qB0l2i9TJ9i+ +/w0EsmtWJqcCWzmvZkA/bw+qayVfibsvt+JDMRQ4aq+aGYVvj6OJ3SKK7mHqk/3I +9g2Dht4RCPVbjmRcy7juMAZOv0i6CNcuQ2OvDPCws/xJt37QMWPLDKLoVqSVjJBX +4ce68olGA3UtvSPXle5ZGQgBsm/jYgcjWixGcDXI1qNxdzJ6k3CcWfOUELKxwxyq +GnDMZ/e/mDHEx5k63xMxy4DdCIvhlHVK263NACsSfLaauw6tECgsGIGduCcAwyTH +Uc/yAndcKaCG3ud93eiQBkbglu+xw/H5zlNT3oWYlmi9irHaFogMQgdMLYpwMlJ1 +1ALiZsOryfd249dgZo9PWwtT82pp8SorcNI0KH+ZUVzdBLQnlCTNlnWoDM5tltwS +khALWmLC3aP2HQJxsTb7mqvNDG4RR199D5IafsyGSYz2p2Cb2oYXoNR4P+fQb21y +hFL7/g6NVwF9vRVqyCmIWhaj0bXYY0zyP7psVNyfYm5YI4z2HBNU+OosvHFFp88o +ivns78fpQl6ww5tOzJ2OXMMa5ZC6VHq177eabCAbpYQUBqWHGYsA20+dZ8H9WD6o +-----END RSA PRIVATE KEY----- diff --git a/work/ca/private/localhost.decrypted.key.pem b/work/ca/private/localhost.decrypted.key.pem new file mode 100644 index 00000000..43b2230b --- /dev/null +++ b/work/ca/private/localhost.decrypted.key.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAyd0VF1CaRaqS9HWZagT6ngLwXCaf3y/pJTQpF0K7tciRXlJA +wkOy6G0NPqzMTn6ePUhj3xOmXEF+GrH8u9jBGvow14PjJBN/nEV3NV21CHnuILg5 +t/Un1vC46Q7pRbdz+KoEX67FF+emehF+u4zPKDFq/QebThwMdQ4JdfgqmkNFB/Hl +4eD7eY/TX/NiLVcaD5XAQ8bUPyeIi8GtbUPYhl+KJj62J/uOK41lH+S+KRqg698y +chaWxZLMKnUkA5GlXwqxwOiQqqw/Z3ERYMKao0d9BSmpxoNy/UAn6g/LOuuA0rkQ +G1i6y1Hl35LY5NNoP3mG9jwjLc05cneb7fJT1wIDAQABAoIBAQC1GOVyDDrLI1NB +gztGFP9twL84POKSjV4BpYDzwEe8txpLX0l/vtKDmEoYn1ePWCLIYehPWkaWX58t +fd55++SKOkiVIFonpGKIpP1kYBQobZMHwZ7ufT7nowCQ/XKjvAiL3qOb36QsZQNC +Ye2rfpDewy7zn95hveIjJZuxPRmjV/v+BD4nb9ul1ivyg+sKbpefJ2nIYjnTt6yw +3j7AZcm0Rl1+biqpeUMRaOOeeVOuqPRYAQIgQo34Y1o191Ss39nJYHj2Maj4eg6+ +/VzoOKTM714Hk3lydo1B0gABmMpzIjfyTm1e/nzx78dopIKj1QOpBUqxloMqYrR+ +X/SfKtgxAoGBAO5nokM6sNVqGoICP9igNDeWxg4+uRDejGjDcMtKLDvTmz8D/yay +cCQVSgpdPkumKTdhF963Krv5fx1ramafoU1vxPREHj2/pbtGOWhEvsBS8TzDW2Q/ +g9J08TEws3rypa7SP7HmpJ9KPH/A07V4lbwR2+R0XDCcszZgHFATeD7PAoGBANjD +DBJl/VO9noI4c9WQWehG7RThd7Kj8chCFDb91yhh3fh/e/68AewZCoz4a1pFr8UJ +BSwcZfBI849JUmNmEe/bej2XWz23oSAUrVbwwSpFLBg63hF2DWZ9kw74MhdxrolO +w4UZbPdDW0bLd0Sm41BbyFmRWTF1QfPqKW/4Yhx5AoGAIEq/StXvT+kAUC3X0hLZ +H9J3X0SVsrhCUopug8q3NR9TfvSeofI3iFut3LuGjZ6jJJItNoie7Dk+Q5DiJ6Zl +peSGzANSCVElNLmtWvc80zYo4O8hOPH1fBNE/EG5feTSFlz6LbGtCLp4eWF4C7Oa +rI/KtiYguqDvEWVxUFNizTcCgYBbTYUHNuiG3mcm6Mp52YzVVxLD6di2aXINbTAA +ndmEC/0oj+JVwTF6Fm4oRPdLFfFcqFkCZI/Xr5LP9w16CuNhSexqhxeKno+C6NK+ +vThQKsTRC/LAHh603g4UjxziXSMseP3IUZZhbIDFCC0bwMQc9BwnBh8wwvhd2nNL +067X2QKBgBdhrkRbwq2XzXIBKV9sNsvDEkogZV0MeyfcyCOkvwns3cUZ6dxBdBht +aTIUQcOYgUu+VH4vgZk3jg+yDJa5d9+zdLo8b4ZpnBQO35de0Q1NZG5m5xc8m1ep +Ok674i5j/Vsf6aukhd0IbFjtltevhAseyDQ3XXgttftkQVOwYGmc +-----END RSA PRIVATE KEY----- diff --git a/work/ca/private/localhost.key.pem b/work/ca/private/localhost.key.pem new file mode 100644 index 00000000..8ba89b49 --- /dev/null +++ b/work/ca/private/localhost.key.pem @@ -0,0 +1,30 @@ +-----BEGIN RSA PRIVATE KEY----- +Proc-Type: 4,ENCRYPTED +DEK-Info: AES-256-CBC,1D94B83E788F95F399ACDF538C082654 + +88TOmks6zx/kNiMSJw/otTxDCOPDBt2mLCGneUpH5v8Iw2TflYDc/+hUqOE8kRh4 +QID0LO8rdCvrC90vAWijEuHxWGzGICM5NG9TGDbWf/61zk/LyVL4bvJm4YIMzGhM +bjzJMbo/QyREKXgu8jAHJUO7rDQ7SIgPdjw2bZnfkVR30YYZYTyuddPJi1XpJNG4 +lCMNh7/JfxxuWIqSm6vM53rdaJFvZzZtuw+2pP6zleS6zZXDY9+90TeNA0OK5VGl +zmBwKMLe0naCoVztosJknBETjmf0ICLuwNa2wpkIMeWJ12ydHG8prUu7USNTtXX3 +WPWDRTVXwGkl/yyAenLAOQtRTaQFlty63T276+toL0x/pm6Hb16VcJKxA6oBmy7u +AG7k1AlPcDAwA2V5YD89Un+1I8RVJCoFTFyKg6TRnZFzUZnqEWXv/C0+dNl5MA5P +55JP8dBKGNofhzgNLoR+kjiBi1BlN4vUDkmJEQU7yX6BV5h/31oS6/bl6pm7gr+A +4koaaeFfPfNUcS+1tN+WEI1Z1/BIf/77TOwVgdjv1eudHbnFd2TmnkFfEScyjfyP +gVKOaC8Co6HqXZnCFHV5ioRL1bDcawyHEm1j6uGg0HsASVZ2UldnmERUwKykrOL0 +PBidUTItBhuBFkCC3GfHNHriqmyacaCCkOF8McGbl8oBujKA9aFSyOgj2DYqAYyH +ibeBE0JtVjjvdEOZ8zf70U6s7hmRyns1364qhTfV+44quvjB9+6wK0beryZwToU7 +lZdkMMjrRLIrVhl0EuKJE5Tdyxn7w3ADSZEGjEDiQQKY0VA3HS3pNckR4rJY7xmJ +xwgNIOxG2P6O1NOkFZIMSM1CQk3ulfRQ4CUeqK8OtwsCB15dPp/rR5NHZTjveQEB +4FuzWMaqqYbFvIPPRN7uKITJwe0em3X0dS6qaNxd8NVPe5494l2ggy+FU2sjGFGF +nGf7CfHc4xyfmnExlaOlmCXdCYRElq8coNqb3VEBmquLUxxR3v6aQdisENg15ms9 +pUwKZ/PkLuIIGPT/P5Uw9GTOjuFZIlsnTktejLa62C+hI/Th9jtfJ5N7koVEc9Am +MrtaP8ANl7MIariJXuBapNb4l0TyaMyaY2uSIp0gFsO+vwZ3SmQwahx+RUNo1mGy +dPPe6x5oeFcJZXIoKs21PKv6QcS8AUNK4kAh0LfUmgTF21SIjD8v/zgp3PTYsgVZ +uHjM3rLGw0YaOoE9d9C0gf2fXFhKhQJkUdLAFtYx5H0Z20HTzfGMqAQAa6Hd0uyb +FrZNxJaKhknCkhlTwq7f0Rs0eR3kRCIesLVpWiXAY0/o2kDeKVSExewjXGN+QK7a +qPHcvAoUKFQVGs8UpZ01BnwxOkPcPDuZ2x7reJB+SqJ+L/pjOr2CaLJMPHP7BRow +XQDe1cRk0A9DC211DRWWPMt9/asNcZIXhhsneBZ5mwcteoJHXc8jkYJ7B7chd8PM +DgMLU292/bL2+1FQtsQs9H+scHsY492pWDdEU3Ag/Xtk3Wup4F2wt0a+hwvnPGqi +YOZDF2M89P3CzO7iMlQ1O0UMk0icUu9VQNHd6bJk3PUcxkAnK3WDyQT8gqOTtEw0 +-----END RSA PRIVATE KEY----- diff --git a/work/ca/serial b/work/ca/serial new file mode 100644 index 00000000..7d802a3e --- /dev/null +++ b/work/ca/serial @@ -0,0 +1 @@ +1002 diff --git a/work/ca/serial.old b/work/ca/serial.old new file mode 100644 index 00000000..dd117240 --- /dev/null +++ b/work/ca/serial.old @@ -0,0 +1 @@ +1001 diff --git a/work/client-cert.jks b/work/client-cert.jks new file mode 100644 index 00000000..3988d9ea Binary files /dev/null and b/work/client-cert.jks differ diff --git a/work/keystore.jks b/work/keystore.jks new file mode 100644 index 00000000..00da36ef Binary files /dev/null and b/work/keystore.jks differ