diff --git a/.github/dependabot.yml b/.github/dependabot.yml index c8f8016..4ae585a 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -3,6 +3,11 @@ updates: - package-ecosystem: bundler directory: "/" schedule: - interval: daily - time: "13:00" + interval: weekly + open-pull-requests-limit: 10 + +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: weekly open-pull-requests-limit: 10 diff --git a/.github/workflows/auto_release_prep.yml b/.github/workflows/auto_release_prep.yml new file mode 100644 index 0000000..50d172f --- /dev/null +++ b/.github/workflows/auto_release_prep.yml @@ -0,0 +1,12 @@ +name: Automated release prep + +on: + workflow_dispatch: + +jobs: + auto_release_prep: + uses: puppetlabs/release-engineering-repo-standards/.github/workflows/auto_release_prep.yml@v1 + secrets: inherit + with: + project-type: ruby + version-file-path: lib/vmpooler-provider-vsphere/version.rb diff --git a/.github/workflows/dependabot_merge.yml b/.github/workflows/dependabot_merge.yml new file mode 100644 index 0000000..75b9cea --- /dev/null +++ b/.github/workflows/dependabot_merge.yml @@ -0,0 +1,8 @@ +name: Dependabot auto-merge + +on: pull_request + +jobs: + dependabot_merge: + uses: puppetlabs/release-engineering-repo-standards/.github/workflows/dependabot_merge.yml@v1 + secrets: inherit diff --git a/.github/workflows/ensure_label.yml b/.github/workflows/ensure_label.yml new file mode 100644 index 0000000..50a5fa8 --- /dev/null +++ b/.github/workflows/ensure_label.yml @@ -0,0 +1,8 @@ +name: Ensure label + +on: pull_request + +jobs: + ensure_label: + uses: puppetlabs/release-engineering-repo-standards/.github/workflows/ensure_label.yml@v1 + secrets: inherit diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ac38a53..1ba42e5 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,4 +1,4 @@ -name: Release +name: Release Gem on: workflow_dispatch @@ -7,25 +7,77 @@ jobs: runs-on: ubuntu-latest if: github.repository == 'puppetlabs/vmpooler-provider-vsphere' steps: - - uses: actions/checkout@v2 - - name: Get Version - id: gv + - uses: actions/checkout@v4 + + - name: Get Current Version + uses: actions/github-script@v7 + id: cv + with: + script: | + const { data: response } = await github.rest.repos.getLatestRelease({ + owner: context.repo.owner, + repo: context.repo.repo, + }) + console.log(`The latest release is ${response.tag_name}`) + return response.tag_name + result-encoding: string + + - name: Get Next Version + id: nv run: | - echo "::set-output name=ver::$(grep VERSION lib/vmpooler-provider-vsphere/version.rb |rev |cut -d "'" -f2 |rev)" + version=$(grep VERSION lib/vmpooler-provider-vsphere/version.rb |rev |cut -d "'" -f2 |rev) + echo "version=$version" >> $GITHUB_OUTPUT + echo "Found version $version from lib/vmpooler-provider-vsphere/version.rb" + + - name: Generate Changelog + uses: docker://githubchangeloggenerator/github-changelog-generator:1.16.2 + with: + args: >- + --future-release ${{ steps.nv.outputs.version }} + env: + CHANGELOG_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Validate Changelog + run : | + set -e + if [[ -n $(git status --porcelain) ]]; then + echo "Here is the current git status:" + git status + echo + echo "The following changes were detected:" + git --no-pager diff + echo "Uncommitted PRs found in the changelog. Please submit a release prep PR of changes after running `./update-changelog`" + exit 1 + fi + + - name: Generate Release Notes + uses: docker://githubchangeloggenerator/github-changelog-generator:1.16.2 + with: + args: >- + --since-tag ${{ steps.cv.outputs.result }} + --future-release ${{ steps.nv.outputs.version }} + --output release-notes.md + env: + CHANGELOG_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + - name: Tag Release uses: ncipollo/release-action@v1 with: - tag: ${{ steps.gv.outputs.ver }} + tag: ${{ steps.nv.outputs.version }} token: ${{ secrets.GITHUB_TOKEN }} + bodyfile: release-notes.md draft: false prerelease: false - generateReleaseNotes: true - - name: Install Ruby 2.5.8 + + # This step should closely match what is used in `docker/Dockerfile` in vmpooler-deployment + - name: Install Ruby jruby-9.3.6.0 uses: ruby/setup-ruby@v1 with: - ruby-version: '2.5.8' + ruby-version: 'jruby-9.4.3.0' + - name: Build gem run: gem build *.gemspec + - name: Publish gem run: | mkdir -p $HOME/.gem diff --git a/.github/workflows/security.yml b/.github/workflows/security.yml new file mode 100644 index 0000000..ba273f5 --- /dev/null +++ b/.github/workflows/security.yml @@ -0,0 +1,39 @@ +name: Security +on: + workflow_dispatch: + push: + branches: + - main + +jobs: + scan: + name: Mend Scanning + runs-on: ubuntu-latest + steps: + - name: checkout repo content + uses: actions/checkout@v4 + with: + fetch-depth: 1 + - name: setup ruby + uses: ruby/setup-ruby@v1 + with: + ruby-version: 2.7 + # setup a package lock if one doesn't exist, otherwise do nothing + - name: check lock + run: '[ -f "Gemfile.lock" ] && echo "package lock file exists, skipping" || bundle lock' + # install java + - uses: actions/setup-java@v4 + with: + distribution: 'temurin' # See 'Supported distributions' for available options + java-version: '17' + # download mend + - name: download_mend + run: curl -o wss-unified-agent.jar https://unified-agent.s3.amazonaws.com/wss-unified-agent.jar + - name: run mend + run: java -jar wss-unified-agent.jar + env: + WS_APIKEY: ${{ secrets.MEND_API_KEY }} + WS_WSS_URL: https://saas-eu.whitesourcesoftware.com/agent + WS_USERKEY: ${{ secrets.MEND_TOKEN }} + WS_PRODUCTNAME: RE + WS_PROJECTNAME: ${{ github.event.repository.name }} diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index 501403f..1f2f421 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -18,9 +18,9 @@ jobs: strategy: matrix: ruby-version: - - '2.5.8' + - 'jruby-9.4.3.0' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: @@ -34,10 +34,9 @@ jobs: strategy: matrix: ruby-version: - - '2.5.8' - - 'jruby-9.2.12.0' + - 'jruby-9.4.3.0' steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: diff --git a/.github_changelog_generator b/.github_changelog_generator new file mode 100644 index 0000000..db01582 --- /dev/null +++ b/.github_changelog_generator @@ -0,0 +1,3 @@ +project=vmpooler-provider-vsphere +user=puppetlabs +exclude_labels=maintenance \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..8e3ca6b --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,136 @@ +# Changelog + +## [3.3.4](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/3.3.4) (2023-08-30) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/3.3.3...3.3.4) + +**Fixed bugs:** + +- \(maint\) Convert booleans and Time objects to strings when being added to redis [\#51](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/51) ([isaac-hammes](https://github.com/isaac-hammes)) + +## [3.3.3](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/3.3.3) (2023-08-28) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/3.3.2...3.3.3) + +**Fixed bugs:** + +- \(maint\) Update Gemfile.lock and use block for transaction. [\#49](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/49) ([isaac-hammes](https://github.com/isaac-hammes)) + +## [3.3.2](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/3.3.2) (2023-08-23) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/3.3.1...3.3.2) + +**Fixed bugs:** + +- \(maint\) Increase timeout for cloned vms to obtain IPs. [\#47](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/47) ([isaac-hammes](https://github.com/isaac-hammes)) + +## [3.3.1](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/3.3.1) (2023-08-22) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/3.3.0...3.3.1) + +**Fixed bugs:** + +- \(RE-15710\) Fix IP address that is returned and increase timeout [\#44](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/44) ([yachub](https://github.com/yachub)) + +## [3.3.0](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/3.3.0) (2023-08-18) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/3.2.0...3.3.0) + +**Implemented enhancements:** + +- \(POD-10\) Log reason for failed VM checks. [\#42](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/42) ([isaac-hammes](https://github.com/isaac-hammes)) + +## [3.2.0](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/3.2.0) (2023-08-10) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/3.1.0...3.2.0) + +**Implemented enhancements:** + +- Bump jruby to 9.4.3.0 and update lockfile [\#40](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/40) ([yachub](https://github.com/yachub)) + +**Merged pull requests:** + +- Bump thor from 1.2.1 to 1.2.2 [\#38](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/38) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump vmpooler from 3.0.0 to 3.1.0 [\#37](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/37) ([dependabot[bot]](https://github.com/apps/dependabot)) +- Bump rack-test from 2.0.2 to 2.1.0 [\#36](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/36) ([dependabot[bot]](https://github.com/apps/dependabot)) + +## [3.1.0](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/3.1.0) (2023-05-01) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/3.0.0...3.1.0) + +**Merged pull requests:** + +- Migrate issue management to Jira [\#34](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/34) ([yachub](https://github.com/yachub)) +- Bump jruby to 9.4.2.0 [\#33](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/33) ([yachub](https://github.com/yachub)) + +## [3.0.0](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/3.0.0) (2023-04-19) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/2.1.0...3.0.0) + +**Breaking changes:** + +- \(RE-15124\) Collect VMs IP for use with DNS Plugins [\#29](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/29) ([yachub](https://github.com/yachub)) + +## [2.1.0](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/2.1.0) (2023-03-06) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/2.0.0...2.1.0) + +**Implemented enhancements:** + +- \(RE-15161\) Use timeout builtin to TCPSocket when opening sockets. [\#30](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/30) ([isaac-hammes](https://github.com/isaac-hammes)) + +## [2.0.0](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/2.0.0) (2023-01-30) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/1.6.0...2.0.0) + +**Implemented enhancements:** + +- Migrate to rbvmomi2 [\#25](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/25) ([yachub](https://github.com/yachub)) + +**Closed issues:** + +- Document Custom VM Attribute [\#23](https://github.com/puppetlabs/vmpooler-provider-vsphere/issues/23) + +**Merged pull requests:** + +- Fix workflow deprecations, changelog, and add docs [\#24](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/24) ([yachub](https://github.com/yachub)) +- \(RE-15111\) Migrate Snyk to Mend Scanning [\#22](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/22) ([yachub](https://github.com/yachub)) +- \(RE-14811\) Remove DIO as codeowners [\#21](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/21) ([yachub](https://github.com/yachub)) +- Add Snyk action [\#20](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/20) ([yachub](https://github.com/yachub)) +- Add release-engineering to codeowners [\#19](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/19) ([yachub](https://github.com/yachub)) +- Update rubocop requirement from ~\> 1.1.0 to ~\> 1.28.2 [\#17](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/17) ([dependabot[bot]](https://github.com/apps/dependabot)) + +## [1.6.0](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/1.6.0) (2022-07-25) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/1.5.0...1.6.0) + +**Merged pull requests:** + +- pin to vmpooler 2.4 [\#18](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/18) ([sbeaulie](https://github.com/sbeaulie)) + +## [1.5.0](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/1.5.0) (2021-12-13) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/1.4.0...1.5.0) + +**Merged pull requests:** + +- Bump version to 1.5.0, require vmpooler \>= 2.1 [\#5](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/5) ([genebean](https://github.com/genebean)) +- Move vsphere specific methods out of vmpooler [\#4](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/4) ([sbeaulie](https://github.com/sbeaulie)) + +## [1.4.0](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/1.4.0) (2021-12-08) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/1.3.0...1.4.0) + +**Merged pull requests:** + +- Prep for initial standalone release: v1.4.0 [\#3](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/3) ([genebean](https://github.com/genebean)) +- Add GH Action for releasing gems [\#2](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/2) ([genebean](https://github.com/genebean)) +- Fix naming, add docs, add missing test file [\#1](https://github.com/puppetlabs/vmpooler-provider-vsphere/pull/1) ([genebean](https://github.com/genebean)) + +## [1.3.0](https://github.com/puppetlabs/vmpooler-provider-vsphere/tree/1.3.0) (2021-11-29) + +[Full Changelog](https://github.com/puppetlabs/vmpooler-provider-vsphere/compare/a08cba099f867b1db01a50940ec3ae9239245db5...1.3.0) + + + +\* *This Changelog was automatically generated by [github_changelog_generator](https://github.com/github-changelog-generator/github-changelog-generator)* diff --git a/CODEOWNERS b/CODEOWNERS index 9c4ecfc..b47017c 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,10 +1,10 @@ -# This will cause DIO to be assigned review of any opened PRs against +# This will cause RE to be assigned review of any opened PRs against # the branches containing this file. # See https://help.github.com/en/articles/about-code-owners for info on how to # take ownership of parts of the code base that should be reviewed by another # team. -# DIO will be the default owners for everything in the repo. -* @puppetlabs/dio +# RE will be the default owners for everything in the repo. +* @puppetlabs/release-engineering diff --git a/Gemfile.lock b/Gemfile.lock index 6811abd..6d96901 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,183 +1,190 @@ PATH remote: . specs: - vmpooler-provider-vsphere (1.5.0) - rbvmomi (>= 2.1, < 4.0) + vmpooler-provider-vsphere (3.3.4) + rbvmomi2 (>= 3.1, < 4.0) + vmpooler (~> 3.0) GEM remote: https://rubygems.org/ specs: ast (2.4.2) - bindata (2.4.10) + bindata (2.4.15) builder (3.2.4) - climate_control (1.0.1) + climate_control (1.2.0) coderay (1.1.3) - concurrent-ruby (1.1.9) - connection_pool (2.2.5) - diff-lcs (1.4.4) + concurrent-ruby (1.2.2) + connection_pool (2.4.1) + deep_merge (1.2.2) + diff-lcs (1.5.0) docile (1.4.0) - faraday (1.8.0) - faraday-em_http (~> 1.0) - faraday-em_synchrony (~> 1.0) - faraday-excon (~> 1.1) - faraday-httpclient (~> 1.0.1) - faraday-net_http (~> 1.0) - faraday-net_http_persistent (~> 1.1) - faraday-patron (~> 1.0) - faraday-rack (~> 1.0) - multipart-post (>= 1.2, < 3) + faraday (2.7.10) + faraday-net_http (>= 2.0, < 3.1) ruby2_keywords (>= 0.0.4) - faraday-em_http (1.0.0) - faraday-em_synchrony (1.0.0) - faraday-excon (1.1.0) - faraday-httpclient (1.0.1) - faraday-net_http (1.0.1) - faraday-net_http_persistent (1.2.0) - faraday-patron (1.0.0) - faraday-rack (1.0.0) - ffi (1.15.4-java) - google-cloud-env (1.5.0) - faraday (>= 0.17.3, < 2.0) - json (2.6.1) - json (2.6.1-java) + faraday-net_http (3.0.2) + ffi (1.15.5-java) + google-cloud-env (1.6.0) + faraday (>= 0.17.3, < 3.0) + json (2.6.3) + json (2.6.3-java) method_source (1.0.0) - mock_redis (0.29.0) - ruby2_keywords - multipart-post (2.1.1) - mustermann (1.1.1) + mock_redis (0.37.0) + mustermann (3.0.0) ruby2_keywords (~> 0.0.1) - net-ldap (0.17.0) - nio4r (2.5.8) - nio4r (2.5.8-java) - nokogiri (1.12.5-java) + net-ldap (0.18.0) + nio4r (2.5.9) + nio4r (2.5.9-java) + nokogiri (1.15.4-java) racc (~> 1.4) - nokogiri (1.12.5-x86_64-linux) + nokogiri (1.15.4-x86_64-linux) racc (~> 1.4) - opentelemetry-api (0.17.0) - opentelemetry-common (0.17.0) - opentelemetry-api (~> 0.17.0) - opentelemetry-exporter-jaeger (0.17.0) - opentelemetry-api (~> 0.17.0) - opentelemetry-common (~> 0.17.0) - opentelemetry-sdk (~> 0.17.0) + opentelemetry-api (1.2.2) + opentelemetry-common (0.20.0) + opentelemetry-api (~> 1.0) + opentelemetry-exporter-jaeger (0.23.0) + opentelemetry-api (~> 1.1) + opentelemetry-common (~> 0.20) + opentelemetry-sdk (~> 1.2) + opentelemetry-semantic_conventions thrift - opentelemetry-instrumentation-base (0.17.0) - opentelemetry-api (~> 0.17.0) - opentelemetry-instrumentation-concurrent_ruby (0.17.0) - opentelemetry-api (~> 0.17.0) - opentelemetry-instrumentation-base (~> 0.17.0) - opentelemetry-instrumentation-redis (0.17.0) - opentelemetry-api (~> 0.17.0) - opentelemetry-common (~> 0.17.0) - opentelemetry-instrumentation-base (~> 0.17.0) - opentelemetry-instrumentation-sinatra (0.17.0) - opentelemetry-api (~> 0.17.0) - opentelemetry-instrumentation-base (~> 0.17.0) - opentelemetry-resource_detectors (0.17.0) + opentelemetry-instrumentation-base (0.22.2) + opentelemetry-api (~> 1.0) + opentelemetry-registry (~> 0.1) + opentelemetry-instrumentation-concurrent_ruby (0.21.1) + opentelemetry-api (~> 1.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-http_client (0.22.2) + opentelemetry-api (~> 1.0) + opentelemetry-common (~> 0.20.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-rack (0.23.4) + opentelemetry-api (~> 1.0) + opentelemetry-common (~> 0.20.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-redis (0.25.3) + opentelemetry-api (~> 1.0) + opentelemetry-common (~> 0.20.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-sinatra (0.23.2) + opentelemetry-api (~> 1.0) + opentelemetry-common (~> 0.20.0) + opentelemetry-instrumentation-base (~> 0.22.1) + opentelemetry-instrumentation-rack (~> 0.21) + opentelemetry-registry (0.3.0) + opentelemetry-api (~> 1.1) + opentelemetry-resource_detectors (0.24.1) google-cloud-env - opentelemetry-sdk - opentelemetry-sdk (0.17.0) - opentelemetry-api (~> 0.17.0) - opentelemetry-common (~> 0.17.0) - opentelemetry-instrumentation-base (~> 0.17.0) - optimist (3.0.1) - parallel (1.21.0) - parser (3.0.3.2) + opentelemetry-sdk (~> 1.0) + opentelemetry-sdk (1.3.0) + opentelemetry-api (~> 1.1) + opentelemetry-common (~> 0.20) + opentelemetry-registry (~> 0.2) + opentelemetry-semantic_conventions + opentelemetry-semantic_conventions (1.10.0) + opentelemetry-api (~> 1.0) + optimist (3.1.0) + parallel (1.23.0) + parser (3.2.2.3) ast (~> 2.4.1) + racc pickup (0.0.11) - prometheus-client (2.1.0) - pry (0.14.1) + prometheus-client (4.2.1) + pry (0.14.2) coderay (~> 1.1) method_source (~> 1.0) - pry (0.14.1-java) + pry (0.14.2-java) coderay (~> 1.1) method_source (~> 1.0) spoon (~> 0.0) - puma (5.5.2) + puma (6.3.1) nio4r (~> 2.0) - puma (5.5.2-java) + puma (6.3.1-java) nio4r (~> 2.0) - racc (1.6.0) - racc (1.6.0-java) - rack (2.2.3) - rack-protection (2.1.0) - rack - rack-test (1.1.0) - rack (>= 1.0, < 3) - rainbow (3.0.0) + racc (1.7.1) + racc (1.7.1-java) + rack (2.2.8) + rack-protection (3.1.0) + rack (~> 2.2, >= 2.2.4) + rack-test (2.1.0) + rack (>= 1.3) + rainbow (3.1.1) rake (13.0.6) - rbvmomi (3.0.0) + rbvmomi2 (3.6.1) builder (~> 3.2) json (~> 2.3) - nokogiri (~> 1.10) + nokogiri (~> 1.12, >= 1.12.5) optimist (~> 3.0) - redis (4.5.1) - regexp_parser (2.2.0) - rexml (3.2.5) - rspec (3.10.0) - rspec-core (~> 3.10.0) - rspec-expectations (~> 3.10.0) - rspec-mocks (~> 3.10.0) - rspec-core (3.10.1) - rspec-support (~> 3.10.0) - rspec-expectations (3.10.1) + redis (5.0.7) + redis-client (>= 0.9.0) + redis-client (0.16.0) + connection_pool + regexp_parser (2.8.1) + rexml (3.2.6) + rspec (3.12.0) + rspec-core (~> 3.12.0) + rspec-expectations (~> 3.12.0) + rspec-mocks (~> 3.12.0) + rspec-core (3.12.2) + rspec-support (~> 3.12.0) + rspec-expectations (3.12.3) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-mocks (3.10.2) + rspec-support (~> 3.12.0) + rspec-mocks (3.12.6) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.10.0) - rspec-support (3.10.3) - rubocop (1.1.0) + rspec-support (~> 3.12.0) + rspec-support (3.12.1) + rubocop (1.28.2) parallel (~> 1.10) - parser (>= 2.7.1.5) + parser (>= 3.1.0.0) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 1.8) + regexp_parser (>= 1.8, < 3.0) rexml - rubocop-ast (>= 1.0.1) + rubocop-ast (>= 1.17.0, < 2.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 1.4.0, < 2.0) - rubocop-ast (1.15.0) - parser (>= 3.0.1.1) - ruby-progressbar (1.11.0) + unicode-display_width (>= 1.4.0, < 3.0) + rubocop-ast (1.29.0) + parser (>= 3.2.1.0) + ruby-progressbar (1.13.0) ruby2_keywords (0.0.5) - simplecov (0.21.2) + simplecov (0.22.0) docile (~> 1.1) simplecov-html (~> 0.11) simplecov_json_formatter (~> 0.1) simplecov-html (0.12.3) - simplecov_json_formatter (0.1.3) - sinatra (2.1.0) - mustermann (~> 1.0) - rack (~> 2.2) - rack-protection (= 2.1.0) + simplecov_json_formatter (0.1.4) + sinatra (3.1.0) + mustermann (~> 3.0) + rack (~> 2.2, >= 2.2.4) + rack-protection (= 3.1.0) tilt (~> 2.0) - spicy-proton (2.1.13) + spicy-proton (2.1.15) bindata (~> 2.3) spoon (0.0.6) ffi statsd-ruby (1.5.0) - thor (1.1.0) - thrift (0.15.0) - tilt (2.0.10) - unicode-display_width (1.8.0) - vmpooler (2.1.0) + thor (1.2.2) + thrift (0.18.1) + tilt (2.2.0) + unicode-display_width (2.4.2) + vmpooler (3.5.1) concurrent-ruby (~> 1.1) - connection_pool (~> 2.2) + connection_pool (~> 2.4) + deep_merge (~> 1.2) net-ldap (~> 0.16) - nokogiri (~> 1.10) - opentelemetry-exporter-jaeger (= 0.17.0) - opentelemetry-instrumentation-concurrent_ruby (= 0.17.0) - opentelemetry-instrumentation-redis (= 0.17.0) - opentelemetry-instrumentation-sinatra (= 0.17.0) - opentelemetry-resource_detectors (= 0.17.0) - opentelemetry-sdk (= 0.17.0) + opentelemetry-exporter-jaeger (= 0.23.0) + opentelemetry-instrumentation-concurrent_ruby (= 0.21.1) + opentelemetry-instrumentation-http_client (= 0.22.2) + opentelemetry-instrumentation-redis (= 0.25.3) + opentelemetry-instrumentation-sinatra (= 0.23.2) + opentelemetry-resource_detectors (= 0.24.1) + opentelemetry-sdk (~> 1.3, >= 1.3.0) pickup (~> 0.0.11) - prometheus-client (~> 2.0) - puma (~> 5.0, >= 5.0.4) - rack (~> 2.2) + prometheus-client (>= 2, < 5) + puma (>= 5.0.4, < 7) + rack (>= 2.2, < 4.0) rake (~> 13.0) - redis (~> 4.1) - sinatra (~> 2.0) + redis (~> 5.0) + sinatra (>= 2, < 4) spicy-proton (~> 2.1) statsd-ruby (~> 1.4) yarjuf (2.0.0) @@ -194,12 +201,11 @@ DEPENDENCIES pry rack-test (>= 0.6) rspec (>= 3.2) - rubocop (~> 1.1.0) + rubocop (~> 1.28.2) simplecov (>= 0.11.2) thor (~> 1.0, >= 1.0.1) - vmpooler (~> 2.1) vmpooler-provider-vsphere! yarjuf (>= 2.0) BUNDLED WITH - 2.2.22 + 2.4.10 diff --git a/README.md b/README.md index 57bd71e..b269094 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,12 @@ # vmpooler-provider-vsphere +- [vmpooler-provider-vsphere](#vmpooler-provider-vsphere) + - [Usage](#usage) + - [Custom VM Config Attribute](#custom-vm-config-attribute) + - [Update the Gemfile Lock](#update-the-gemfile-lock) + - [Releasing](#releasing) + - [License](#license) + This is a provider for [VMPooler](https://github.com/puppetlabs/vmpooler) allows using vSphere as a source of machines. This provider was originally part of the main VMPooler code base but was extracted to be a standalone gem so that development could be done independently of VMPooler itself. ## Usage @@ -8,6 +15,30 @@ Include this gem in the same Gemfile that you use to install VMPooler itself and Examples of deploying VMPooler with this provider can be found in the [puppetlabs/vmpooler-deployment](https://github.com/puppetlabs/vmpooler-deployment) repository. +### Custom VM Config Attribute + +This provider sets a custom attribute on the VM called `guestinfo.hostname` to the name of the generated VM, which can be queried from inside the guest OS if VMware Tools is isntalled. For example: + +macOS: `"/Library/Application Support/VMware Tools/vmware-tools-daemon" --cmd "info-get guestinfo.hostname"` +Linux or Windows Guest: `vmtoolsd --cmd "info-get guestinfo.hostname"` + +See the [VMware Tools Administration docs](https://docs.vmware.com/en/VMware-Tools/12.1.0/com.vmware.vsphere.vmwaretools.doc/GUID-D026777B-606D-4442-957A-B953C2049659.html) for more information about querying information from the GuestInfo variable. + +## Update the Gemfile Lock + +To update the `Gemfile.lock` run `./update-gemfile-lock`. + +Verify, and update if needed, that the docker tag in the script and GitHub action workflows matches what is used in the [vmpooler-deployment Dockerfile](https://github.com/puppetlabs/vmpooler-deployment/blob/main/docker/Dockerfile). + +## Releasing + +Follow these steps to publish a new GitHub release, and build and push the gem to . + +1. Bump the "VERSION" in `lib/vmpooler-provider-vsphere/version.rb` appropriately based on changes in `CHANGELOG.md` since the last release. +2. Run `./release-prep` to update `Gemfile.lock` and `CHANGELOG.md`. +3. Commit and push changes to a new branch, then open a pull request against `main` and be sure to add the "maintenance" label. +4. After the pull request is approved and merged, then navigate to Actions --> Release Gem --> run workflow --> Branch: main --> Run workflow. + ## License vmpooler-provider-vsphere is distributed under the [Apache License, Version 2.0](http://www.apache.org/licenses/LICENSE-2.0.html). See the [LICENSE](LICENSE) file for more details. diff --git a/install-gemfile-lock b/install-gemfile-lock new file mode 100755 index 0000000..a479b0d --- /dev/null +++ b/install-gemfile-lock @@ -0,0 +1,7 @@ +#!/usr/bin/env bash + +# The container tag should closely match what is used in `docker/Dockerfile` in vmpooler-deployment +docker run -it --rm \ + -v $(pwd):/app \ + jruby:9.4.3.0-jdk11 \ + /bin/bash -c 'apt-get update -qq && apt-get install -y --no-install-recommends make git netbase && cd /app && gem install bundler && bundle install --jobs 3; echo "LOCK_FILE_UPDATE_EXIT_CODE=$?"' diff --git a/lib/vmpooler-provider-vsphere/version.rb b/lib/vmpooler-provider-vsphere/version.rb index ec8c193..36c56a7 100644 --- a/lib/vmpooler-provider-vsphere/version.rb +++ b/lib/vmpooler-provider-vsphere/version.rb @@ -1,5 +1,5 @@ # frozen_string_literal: true module VmpoolerProviderVsphere - VERSION = '1.5.0' + VERSION = '3.3.4' end diff --git a/lib/vmpooler/providers/vsphere.rb b/lib/vmpooler/providers/vsphere.rb index c572d48..efd3c9f 100644 --- a/lib/vmpooler/providers/vsphere.rb +++ b/lib/vmpooler/providers/vsphere.rb @@ -51,6 +51,11 @@ module Vmpooler 'vsphere' end + def domain(pool_name) + dns_plugin_name = pool_config(pool_name)['dns_plugin'] + dns_config(dns_plugin_name) + end + def folder_configured?(folder_title, base_folder, configured_folders, allowlist) return true if allowlist&.include?(folder_title) return false unless configured_folders.keys.include?(folder_title) @@ -63,14 +68,14 @@ module Vmpooler try = 0 if try.nil? max_tries = 3 @redis.with_metrics do |redis| - redis.multi - redis.srem("vmpooler__completed__#{pool}", vm_name) - redis.hdel("vmpooler__active__#{pool}", vm_name) - redis.hset("vmpooler__vm__#{vm_name}", 'destroy', Time.now) + redis.multi do |transaction| + transaction.srem("vmpooler__completed__#{pool}", vm_name) + transaction.hdel("vmpooler__active__#{pool}", vm_name) + transaction.hset("vmpooler__vm__#{vm_name}", 'destroy', Time.now.to_s) - # Auto-expire metadata key - redis.expire("vmpooler__vm__#{vm_name}", (data_ttl * 60 * 60)) - redis.exec + # Auto-expire metadata key + transaction.expire("vmpooler__vm__#{vm_name}", (data_ttl * 60 * 60)) + end end start = Time.now @@ -387,6 +392,16 @@ module Vmpooler vm_hash end + # The inner method requires vmware tools running in the guest os + def get_vm_ip_address(vm_name, pool_name) + @connection_pool.with_metrics do |pool_object| + connection = ensured_vsphere_connection(pool_object) + vm_object = find_vm(pool_name, vm_name, connection) + vm_hash = generate_vm_hash(vm_object, pool_name) + return vm_hash['ip'] + end + end + def create_config_spec(vm_name, template_name, extra_config) RbVmomi::VIM.VirtualMachineConfigSpec( annotation: JSON.pretty_generate( @@ -540,13 +555,15 @@ module Vmpooler true end - def vm_ready?(_pool_name, vm_name) + def vm_ready?(pool_name, vm_name, redis) begin - open_socket(vm_name, global_config[:config]['domain']) - rescue StandardError => _e + domain = domain(pool_name) + open_socket(vm_name, domain) + rescue StandardError => e + redis.hset("vmpooler__vm__#{vm_name}", 'open_socket_error', e.to_s) return false end - + redis.hdel("vmpooler__vm__#{vm_name}", 'open_socket_error') true end @@ -582,13 +599,30 @@ module Vmpooler boottime = vm_object.runtime.bootTime if vm_object.runtime&.bootTime powerstate = vm_object.runtime.powerState if vm_object.runtime&.powerState + ip_maxloop = 240 + ip_loop_delay = 1 + ip_loop_count = 1 + ip = nil + invalid_addresses = /(0|169)\.(0|254)\.\d+\.\d+/ + while ip.nil? + sleep(ip_loop_delay) + ip = vm_object.guest_ip + ip = nil if !ip.nil? && ip.match?(invalid_addresses) + unless ip_maxloop == 0 + break if ip_loop_count >= ip_maxloop + + ip_loop_count += 1 + end + end + { 'name' => vm_object.name, 'hostname' => hostname, 'template' => pool_configuration['template'], 'poolname' => pool_name, 'boottime' => boottime, - 'powerstate' => powerstate + 'powerstate' => powerstate, + 'ip' => ip } end @@ -632,15 +666,13 @@ module Vmpooler # This should supercede the open_socket method in the Pool Manager def open_socket(host, domain = nil, timeout = 5, port = 22, &_block) - Timeout.timeout(timeout) do - target_host = host - target_host = "#{host}.#{domain}" if domain - sock = TCPSocket.new target_host, port - begin - yield sock if block_given? - ensure - sock.close - end + target_host = host + target_host = "#{host}.#{domain}" if domain + sock = TCPSocket.new(target_host, port, connect_timeout: timeout) + begin + yield sock if block_given? + ensure + sock.close end end @@ -1071,6 +1103,9 @@ module Vmpooler begin connection = ensured_vsphere_connection(pool_object) vm_hash = get_vm_details(pool_name, vm_name, connection) + + raise StandardError, 'failed to get vm details. vm is unreachable or no longer exists' if vm_hash.nil? + @redis.with_metrics do |redis| redis.hset("vmpooler__vm__#{vm_name}", 'host', vm_hash['host_name']) migration_count = redis.scard('vmpooler__migration') @@ -1105,10 +1140,10 @@ module Vmpooler target_host_object = find_host_by_dnsname(connection, target_host_name) finish = migrate_vm_and_record_timing(pool_name, vm_name, vm_hash, target_host_object, target_host_name) @redis.with_metrics do |redis| - redis.multi - redis.hset("vmpooler__vm__#{vm_name}", 'host', target_host_name) - redis.hset("vmpooler__vm__#{vm_name}", 'migrated', true) - redis.exec + redis.multi do |transaction| + transaction.hset("vmpooler__vm__#{vm_name}", 'host', target_host_name) + transaction.hset("vmpooler__vm__#{vm_name}", 'migrated', 'true') + end end logger.log('s', "[>] [#{pool_name}] '#{vm_name}' migrated from #{vm_hash['host_name']} to #{target_host_name} in #{finish} seconds") ensure @@ -1126,10 +1161,10 @@ module Vmpooler metrics.increment("migrate_to.#{dest_host_name}") @redis.with_metrics do |redis| checkout_to_migration = format('%