From ea7e617e453a26f31b9ede3059e87994d8009904 Mon Sep 17 00:00:00 2001 From: Tom Morelly Date: Sat, 29 Jun 2024 21:57:37 +1000 Subject: [PATCH] feat(refactor): plugin refactor for v4 --- .github/workflows/lint.yaml | 36 + .github/workflows/test.yml | 22 +- .gitignore | 5 +- .golang-ci.yml | 34 + .goreleaser.yml | 2 + .pre-commit-config.yaml | 14 + Makefile | 62 ++ README.md | 247 +++++-- docs/docs.pkr.hcl | 81 +++ example/goss/goss.yaml | 47 -- example/http/ks7.cfg | 108 --- example/packer.json | 91 --- example/scripts/cleanup.sh | 11 - example/scripts/vagrant.sh | 31 - example/scripts/zerodisk.sh | 5 - examples/build.pkr.hcl | 31 + examples/dir/dir2/goss.yaml | 3 + examples/goss_included.yaml | 3 + examples/goss_tmpl.yaml | 9 + examples/packer.pkr.hcl | 14 + examples/source.pkr.hcl | 5 + examples/vars.yaml | 1 + go.mod | 234 ++++++- go.sum | 658 +++++++++++++++++- main.go | 8 +- provisioner/goss/goss.go | 107 +++ provisioner/goss/goss_installation.go | 226 ++++++ provisioner/goss/goss_render.go | 217 ++++++ provisioner/goss/goss_test.go | 156 +++++ provisioner/goss/goss_validate.go | 297 ++++++++ provisioner/goss/packer-provisioner-goss.go | 581 ---------------- .../goss/packer-provisioner-goss.hcl2spec.go | 75 -- .../goss/packer-provisioner-goss_test.go | 274 -------- provisioner/goss/provisioner_goss.go | 60 ++ provisioner/goss/provisioner_goss.hcl2spec.go | 121 ++++ provisioner/goss/provisioner_goss_test.go | 72 ++ provisioner/goss/testdata/format.pkr.hcl | 20 + provisioner/goss/testdata/goss.yaml | 3 + provisioner/goss/testdata/goss_tmpl.yaml | 5 + .../goss/testdata/gossfile_included.yaml | 7 + provisioner/goss/testdata/included.pkr.hcl | 25 + provisioner/goss/testdata/latest.pkr.hcl | 16 + provisioner/goss/testdata/vars.pkr.hcl | 23 + provisioner/goss/testdata/vars.yaml | 1 + provisioner/goss/testdata/version.pkr.hcl | 19 + provisioner/goss/types.go | 54 ++ provisioner/goss/utils.go | 67 ++ tools/tools.go | 23 + 48 files changed, 2864 insertions(+), 1347 deletions(-) create mode 100644 .github/workflows/lint.yaml create mode 100644 .golang-ci.yml create mode 100644 .pre-commit-config.yaml create mode 100644 Makefile create mode 100644 docs/docs.pkr.hcl delete mode 100644 example/goss/goss.yaml delete mode 100644 example/http/ks7.cfg delete mode 100644 example/packer.json delete mode 100644 example/scripts/cleanup.sh delete mode 100644 example/scripts/vagrant.sh delete mode 100644 example/scripts/zerodisk.sh create mode 100644 examples/build.pkr.hcl create mode 100644 examples/dir/dir2/goss.yaml create mode 100644 examples/goss_included.yaml create mode 100644 examples/goss_tmpl.yaml create mode 100644 examples/packer.pkr.hcl create mode 100644 examples/source.pkr.hcl create mode 100644 examples/vars.yaml create mode 100644 provisioner/goss/goss.go create mode 100644 provisioner/goss/goss_installation.go create mode 100644 provisioner/goss/goss_render.go create mode 100644 provisioner/goss/goss_test.go create mode 100644 provisioner/goss/goss_validate.go delete mode 100644 provisioner/goss/packer-provisioner-goss.go delete mode 100644 provisioner/goss/packer-provisioner-goss.hcl2spec.go delete mode 100644 provisioner/goss/packer-provisioner-goss_test.go create mode 100644 provisioner/goss/provisioner_goss.go create mode 100644 provisioner/goss/provisioner_goss.hcl2spec.go create mode 100644 provisioner/goss/provisioner_goss_test.go create mode 100644 provisioner/goss/testdata/format.pkr.hcl create mode 100644 provisioner/goss/testdata/goss.yaml create mode 100644 provisioner/goss/testdata/goss_tmpl.yaml create mode 100644 provisioner/goss/testdata/gossfile_included.yaml create mode 100644 provisioner/goss/testdata/included.pkr.hcl create mode 100644 provisioner/goss/testdata/latest.pkr.hcl create mode 100644 provisioner/goss/testdata/vars.pkr.hcl create mode 100644 provisioner/goss/testdata/vars.yaml create mode 100644 provisioner/goss/testdata/version.pkr.hcl create mode 100644 provisioner/goss/types.go create mode 100644 provisioner/goss/utils.go create mode 100644 tools/tools.go diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml new file mode 100644 index 0000000..de7e1be --- /dev/null +++ b/.github/workflows/lint.yaml @@ -0,0 +1,36 @@ +name: golangci-lint +on: + push: + paths: + - '**.go' + branches: + - master + pull_request: + +permissions: + # Required: allow read access to the content for analysis. + contents: read + # Optional: allow read access to pull request. Use with `only-new-issues` option. + pull-requests: read + # Optional: Allow write access to checks to allow the action to annotate code in the PR. + checks: write + +jobs: + golangci: + name: lint + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-go@v5 + with: + go-version: '1.21' + cache: false + + - name: golangci-lint + uses: golangci/golangci-lint-action@v6 + with: + version: v1.59.1 + args: -c .golang-ci.yml -v --timeout=5m + env: + GO111MODULES: off diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 4732093..9668ae0 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -9,14 +9,30 @@ jobs: steps: - uses: actions/checkout@v4 - - uses: actions/setup-go@v5 with: go-version: '1.21' cache: false + - run: go generate -tags tools tools/tools.go + + - uses: hashicorp/setup-packer@main + + - run: | + make build + make install + packer plugin install github.com/hashicorp/docker + - name: go get run: go get ./... - - name: Run tests - run: go test -v ./... + - name: unit tests + run: make test + env: + PACKER_ACC: 1 + + - name: acc tests + run: make test-acc + + - name: e2e tests + run: make test-e2e \ No newline at end of file diff --git a/.gitignore b/.gitignore index 5cad884..5272e6b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ -example/packer_cache \ No newline at end of file +.envrc +packer-plugin-goss +**/*.tar +**/test-results.xml \ No newline at end of file diff --git a/.golang-ci.yml b/.golang-ci.yml new file mode 100644 index 0000000..c8edf71 --- /dev/null +++ b/.golang-ci.yml @@ -0,0 +1,34 @@ +linters-settings: + lll: + line-length: 180 + allow-leading-space: true +linters: + enable-all: true + disable: + - testpackage + - forbidigo + - paralleltest + - wrapcheck + - gochecknoglobals + - varnamelen + - funlen + - gomnd + - containedctx + - nlreturn + - wsl + - err113 + - exhaustruct + - nolintlint + - maintidx + - dupl + - revive + - depguard + - tagalign + - perfsprint + - godox + - intrange + - copyloopvar + - gomoddirectives + - goconst + - godot + - execinquery \ No newline at end of file diff --git a/.goreleaser.yml b/.goreleaser.yml index 552cbb1..086ba56 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -4,8 +4,10 @@ env: - PACKER_PROTOCOL_VERSION=x5.0 before: hooks: + - go generate -tags tools tools/tools.go - go mod tidy - go test ./... + - make plugin-check builds: - id: plugin-check diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 0000000..331f356 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,14 @@ +repos: + - repo: https://github.com/tekwizely/pre-commit-golang + rev: v1.0.0-rc.1 + hooks: + - id: go-build-mod + - id: go-test-mod + - id: go-vet-mod + - id: go-staticcheck-mod + - id: go-fmt + - id: go-fumpt + - id: go-imports + - id: go-lint + - id: golangci-lint-mod + args: [-c.golang-ci.yml] \ No newline at end of file diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7a09185 --- /dev/null +++ b/Makefile @@ -0,0 +1,62 @@ +E2E_DIR ?= examples + +default: help + +.PHONY: help +help: ## list makefile targets + @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sort | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-30s\033[0m %s\n", $$1, $$2}' + +PHONY: lint +lint: ## lint go files + golangci-lint run -c .golang-ci.yml + +.PHONY: fmt +fmt: ## format go files + gofumpt -w . + gci write . + packer fmt -recursive -write . + +.PHONY: build +build: ## build the plugin + go build -ldflags="-X github.com/YaleUniversity/packer-provisioner-goss/version.VersionPrerelease=dev" -o packer-plugin-goss + +.PHONY: install +install: build ## install the plugin + packer plugins install --path packer-plugin-goss github.com/YaleUniversity/goss + +.PHONY: test +test: ## run tests + PACKER_ACC=1 gotestsum + +.PHONY: test-acc +test-acc: clean build install ## run acceptance tests + PACKER_ACC=1 go test -count 1 -v ./provisioner/goss/provisioner_goss_test.go -timeout=120m + +.PHONY: test-e2e +test-e2e: clean build install ## run e2e tests + cd $(E2E_DIR) && packer init . + cd $(E2E_DIR) && packer build . + +.PHONY: clean +clean: ## remove tmp files + rm -f $(E2E_DIR)/*.tar $(E2E_DIR)/test-results.xml packer-plugin-goss + +.PHONY: generate +generate: ## go generate + go generate ./... + +.PHONY: plugin-check +plugin-check: build ## will check whether a plugin binary seems to work with packer + @packer-sdc plugin-check packer-plugin-goss + +.PHONY: docs +docs: ## gen packer plugin docs + @go generate ./... + @rm -rf .docs + @packer-sdc renderdocs -src "docs" -partials docs-partials/ -dst ".docs/" + @./.web-docs/scripts/compile-to-webdocs.sh "." ".docs" ".web-docs" "YaleUniversity" + @rm -r ".docs" + +.PHONY: example +example: install ## run example + cd examples && packer build . \ No newline at end of file diff --git a/README.md b/README.md index 2cfe159..7c9da8c 100644 --- a/README.md +++ b/README.md @@ -1,107 +1,224 @@ # Goss Packer Provisioner -Wouldn't it be nice if you could run [goss](https://github.com/aelsabbahy/goss) tests against an image during a packer build? +Wouldn't it be nice if you could run [goss](https://github.com/goss-org/goss) tests against an image during a packer build? Well, I thought it would, so now you can! This runs during the provisioning process since the machine being provisioned is only available at that time. -There is an example packer build with goss tests in the `example/` directory. ## Configuration - ```hcl packer { required_version = ">= 1.9.0" required_plugins { goss = { - version = "~> 3" + version = "~> 4" source = "github.com/YaleUniversity/goss" } } } ``` -### Additional (optional) properties - +## Usage ```hcl build { - sources = [".."] - + sources = [""] + provisioner "goss" { - # Provisioner Args - arch ="amd64" - download_path = "/tmp/goss-VERSION-linux-ARCH" - inspect = "{{ inspect_mode }}", - password = "" - skip_install = false - url = "https://github.com/aelsabbahy/goss/releases/download/vVERSION/goss-linux-ARCH" - username = "" - version = "0.3.2" - - # GOSS Args - tests = [ - "goss/goss.yaml" - ] - - remote_folder = "/tmp" - remote_path = "/tmp/goss" - skip_ssl = false - use_sudo = false - format = "" - goss_file = "" - vars_file = "" - target_os = "Linux" - - vars_env = { - ARCH = "amd64" - PROVIDER = "{{ cloud-provider }}" - } - vars_inline = { - OS = "centos", - version = "{{ version }}" + # block specifying any goss download parameters. Goss is downloaded using curl and wget as a fallback installation method + installation { + # wether to use sudo for the curl/wget download; # optional; default: false + use_sudo = false + + # the goss version to download; optional; default: "latest" + version = "latest" + + # the architecture to download; optional; default: "amd64" + arch = "amd64" + + # the operating system to download; optional; default: "Linux", options: "Windows", "Linux" + os = "" + + # the url to download goss from; optional; default: "https://github.com/goss-org/goss/releases/download/{{ Version }}/goss-{{ Version }}-{{ Os }}-{{ Arch }}" + url = "" + + # the checksum to verify the downloaded goss binary; optional; default: false + skip_ssl = false + + # the path to download goss to; optional; default: "/tmp/goss-{{ Version }}-{{ Os }}-{{ Arch }}" + download_path = "" + + # username for basic auth; optional; default: "" + username = "" + + # password for basic auth; optional; default: "" + password = "" + + # a map of any extra env vars to pass to the download request; optional; default: {} + env_vars = nil + + # wether to skip the installation + skip_installation = false } - retry_timeout = "0s" - sleep = "1s" + # block specifying any goss validate parameters + validate { + # wether to use sudo for the goss validate command; # optional; default: false + use_sudo = false + + # the path to cd into before running goss validate; optional; default: "/tmp/" + remote_path = "" + + # a goss vars file; optional; default: "" + vars_file = "" + + # a gossfile; optional; default: "./goss.yaml" + goss_file = "" + + # a map of any goss inline vars for rendering a gossfile; optional; default: {} + vars_inline = nil + + # a map of any extra env vars to pass to the download request; optional; default: {} + env_vars = nil + + # where to write the goss test results to; optional; default: "" + output_file = "" + + # a retry timeout for goss validate; optional; default: "0s" + retry_timeut = "" + + # a sllep timeout for goss validate; optonal; default: "1s" + sleep = "" + + # the goss test results format; optional; values: "documentation", "json", "json_oneline", "junit", "nagios", "nagios_verbose", "rspecish", "silent", "tap" + format = "" + + # the goss test results format options; values; default: "perfdata", "verbose", "pretty" + format_options = "" + } } } ``` -## Spec files -Goss spec file and debug spec file (`goss render -d`) are downloaded to `/tmp` folder on local machine from the remote VM. These files are exact specs GOSS validated on the VM. The downloaded GOSS spec can be used to validate any other VM image for equivalency. +## Getting Started +This is an example `packer` project using `packers` `docker` builder to build an `alpine` container and running tests against it using the `goss` provisioner. -## Windows support +### 1. Required Plugin definition +Define the required plugins: -This now has support for Windows. Set the optional parameter `target_os` to `Windows`. Currently, the `vars_env` parameter must include `GOSS_USE_ALPHA=1` as specified in [goss's feature parity document](https://github.com/aelsabbahy/goss/blob/master/docs/platform-feature-parity.md#platform-feature-parity). In the future when goss come of of alpha for Windows this parameter will not be required. +```hcl +# examples/packer.pkr.hcl +packer { + required_version = ">= 1.9.0" -## Build + required_plugins { + goss = { + version = "~> 4" + source = "github.com/YaleUniversity/goss" + } + docker = { + source = "github.com/hashicorp/docker" + version = "v1.0.10" + } + } +} +``` -### Using Golang docker image +### 2. Build Sources +Define a `source.docker.linux` block that fetches an `alpine` container, applies the build specs and exports the container to `linux.tar`: -```bash -docker run --rm -it -v "$PWD":/usr/src/packer-provisioner-goss -w /usr/src/packer-provisioner-goss -e 'VERSION=v1.0.0' golang:1.13 bash -go test ./... -for GOOS in darwin linux windows; do - for GOARCH in 386 amd64; do - export GOOS GOARCH - go get -v ./... - go build -v -o packer-provisioner-goss-${VERSION}-$GOOS-$GOARCH - done -done +```hcl +# examples/source.pkr.hcl +# fetch a normal alpine container and export the image as alpine.tar +source "docker" "linux" { + image = "alpine" + export_path = "linux.tar" +} ``` -## Author +### 3. Build instructions +Define a `build` block, that references the source `docker.linux` and configure the `goss` provisioner to run tests against it. -E. Camden Fisher +This example showcases a lot of `goss` features, such as includings, templating and variables. -## License +This blocks specifies to install `goss` in version `0.4.2`. Sets `goss_templ.yaml` as the main `gossfile` and passes a `vars.yaml` as the vars file. Note that `goss_templ.yaml` includes two other `gossfiles` that are also included by the `goss`-provisioner and copied to the target machine. Additionally it sets an inline var `pkg_installed` to `true` and an env var of `curl_installed` to `false`. The results of `goss` are written in `junit` format to `test-results.xml`, which will be downloaded from the target machine to the node that is executing `packer` and written to the specified path. -### MIT +Please pay attention to the file paths of any included Var or gossfiles. It is recommended to `packer build` from the same directory, where the `packer` files are located -Copyright 2017-2021 Yale University +```hcl +# examples/build.pkr.hcl +build { + # apply build params against the alpine container + sources = ["docker.linux"] -Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + # run goss tests using goss provisioner + provisioner "goss" { + + # goss download parameter + installation { + version = "0.4.2" + } -The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + # goss validate parameter + validate { + goss_file = "./goss_tmpl.yaml" + vars_file = "./vars.yaml" -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + vars_inline = { + pkg_installed = true + } + + env_vars = { + curl_installed = false + } + + format = "junit" + format_options = "pretty" + output_file = "test-results.xml" + } + } +} +``` + +### 4. Build and Verify +The final rendered and merged `gossfile` used here, looks like this: + +```bash +$> curl_installed=true goss -g goss_tmpl.yaml --vars vars.yaml --vars-inline "pkg_installed: true" render +package: + ansible: + installed: true + curl: + installed: false + telnet: + installed: true + terraform: + installed: true +``` + +Which will test, whether `ansible`, `telnet` and `terraform` are installed and `curl` is absent. + +When running `cd examples && packer build .` (or `make example`), you should see `packer` fetching the `alpine` container and applying the build instruction and running the `goss` tests. The `junit` test results file (`examples/test-results.xml`) will be available, as well as the exported `alpine` container (`examples/linux.tar`): + +```bash +$> file examples/linux.tar +examples/linux.tar: POSIX tar archive +$> cat examples/test-results.xml + + + +Package: terraform: installed: Expected false to equal true +Package: terraform: installed: Expected false to equal true + + +Package: curl: installed: matches expectation: false + + +Package: telnet: installed: Expected false to equal true +Package: telnet: installed: Expected false to equal true + + +Package: ansible: installed: Expected false to equal true +Package: ansible: installed: Expected false to equal true + +``` \ No newline at end of file diff --git a/docs/docs.pkr.hcl b/docs/docs.pkr.hcl new file mode 100644 index 0000000..66ac334 --- /dev/null +++ b/docs/docs.pkr.hcl @@ -0,0 +1,81 @@ +build { + sources = [""] + + provisioner "goss" { + + # block specifying any goss download parameters. Goss is downloaded using curl and wget as a fallback installation method + installation { + # wether to use sudo for the curl/wget download; # optional; default: false + use_sudo = false + + # the goss version to download; optional; default: "latest" + version = "latest" + + # the architecture to download; optional; default: "amd64" + arch = "amd64" + + # the operating system to download; optional; default: "Linux", options: "Windows", "Linux" + os = "Linux" + + # the url to download goss from; optional; default: "https://github.com/goss-org/goss/releases/download/{{ Version }}/goss-{{ Version }}-{{ Os }}-{{ Arch }}" + url = "" + + # the checksum to verify the downloaded goss binary; optional; default: false + skip_ssl = false + + # the path to download goss to; optional; default: "/tmp/goss-{{ Version }}-{{ Os }}-{{ Arch }}" + download_path = "" + + # username for basic auth; optional; default: "" + username = "" + + # password for basic auth; optional; default: "" + password = "" + + # a map of any extra env vars to pass to the download request; optional; default: {} + env_vars = {} + + # wether to skip the installation + skip_installation = false + } + + # block specifying any goss validate parameters + validate { + # wether to use sudo for the goss validate command; # optional; default: false + use_sudo = false + + # a goss vars file; optional; default: "" + vars_file = "" + + # a gossfile; optional; default: "./goss.yaml" + goss_file = "" + + # a map of any goss inline vars for rendering a gossfile; optional; default: {} + vars_inline = {} + + # a map of any extra env vars to pass to the download request; optional; default: {} + env_vars = {} + + # loglevel; optional; values: "TRACE", "DEBUG", "INFO", "WARN", "ERROR" + log_level = "" + + # package type; optional; values: "apk", "dpkg", "pacman", "rpm" + package = "" + + # a retry timeout for goss validate; optional; default: "0s" + retry_timeut = "" + + # a sllep timeout for goss validate; optonal; default: "1s" + sleep = "" + + # the goss test results format; optional; values: "documentation", "json", "json_oneline", "junit", "nagios", "nagios_verbose", "rspecish", "silent", "tap" + format = "" + + # the goss test results format options; values; default: "perfdata", "verbose", "pretty" + format_options = "" + + # where to write the goss test results to; optional; default: "" + output_file = "" + } + } +} \ No newline at end of file diff --git a/example/goss/goss.yaml b/example/goss/goss.yaml deleted file mode 100644 index ba5f41e..0000000 --- a/example/goss/goss.yaml +++ /dev/null @@ -1,47 +0,0 @@ -port: - tcp:22: - listening: true - ip: - - 0.0.0.0 - tcp6:22: - listening: true - ip: - - '::' -service: - sshd: - enabled: true - running: true -user: - sshd: - exists: true - uid: 74 - gid: 74 - groups: - - sshd - home: /var/empty/sshd - shell: /sbin/nologin - vagrant: - exists: true - groups: - - vagrant - - wheel - home: /home/vagrant -group: - sshd: - exists: true - gid: 74 - vagrant: - exists: true -process: - sshd: - running: true -file: - /home/vagrant/.ssh: - exists: true - filetype: directory - /home/vagrant/.ssh/authorized_keys: - filetype: file - exists: true - mode: "0600" - owner: vagrant - group: vagrant \ No newline at end of file diff --git a/example/http/ks7.cfg b/example/http/ks7.cfg deleted file mode 100644 index 0e269ab..0000000 --- a/example/http/ks7.cfg +++ /dev/null @@ -1,108 +0,0 @@ -install -url --url=http://mirrors.kernel.org/centos/7/os/x86_64 - -lang en_US.UTF-8 -keyboard us -timezone America/New_York - -network --bootproto=dhcp -firewall --disabled - -authconfig --enableshadow --passalgo=sha512 -selinux --disabled -rootpw changeme - -text -skipx - -clearpart --all --initlabel -zerombr -autopart -bootloader --location=mbr - -firstboot --disabled -reboot - -%packages --nobase --ignoremissing --excludedocs -# vagrant needs this to copy initial files via scp -openssh-clients -sudo -kernel-headers -kernel-devel -gcc -make -perl -wget -nfs-utils -net-tools -bzip2 - --fprintd-pam --intltool --avahi --bluez-utils --dogtail --kudzu - -# unnecessary firmware --aic94xx-firmware --atmel-firmware --b43-openfwwf --bfa-firmware --ipw2100-firmware --ipw2200-firmware --ivtv-firmware --iwl100-firmware --iwl105-firmware --iwl135-firmware --iwl1000-firmware --iwl2000-firmware --iwl2030-firmware --iwl3160-firmware --iwl3945-firmware --iwl4965-firmware --iwl5000-firmware --iwl5150-firmware --iwl6000-firmware --iwl6000g2a-firmware --iwl6000g2b-firmware --iwl6050-firmware --iwl7260-firmware --libertas-usb8388-firmware --libertas-sd8686-firmware --libertas-sd8787-firmware --ql2100-firmware --ql2200-firmware --ql23xx-firmware --ql2400-firmware --ql2500-firmware --rt61pci-firmware --rt73usb-firmware --xorg-x11-drv-ati-firmware --zd1211-firmware -%end - -%post -yum update -y - -# disable unnecessary services -chkconfig acpid off -chkconfig auditd off -chkconfig blk-availability off -chkconfig bluetooth off -chkconfig certmonger off -chkconfig cpuspeed off -chkconfig cups off -chkconfig haldaemon off -chkconfig ip6tables off -chkconfig lvm2-monitor off -chkconfig messagebus off -chkconfig mdmonitor off -chkconfig rpcbind off -chkconfig rpcgssd off -chkconfig rpcidmapd off -chkconfig yum-updateonboot off - -echo 'useDNS no' >> /etc/ssh/sshd_config -yum clean all -%end diff --git a/example/packer.json b/example/packer.json deleted file mode 100644 index 1b06791..0000000 --- a/example/packer.json +++ /dev/null @@ -1,91 +0,0 @@ -{ - "builders": [ - { - "boot_command": [ - " text ks=http://{{ .HTTPIP }}:{{ .HTTPPort }}/ks7.cfg" - ], - "boot_wait": "10s", - "communicator": "ssh", - "disk_size": 10240, - "guest_os_type": "RedHat_64", - "hard_drive_interface": "scsi", - "headless": true, - "http_directory": "http", - "iso_checksum": "sha256:{{user `iso_checksum`}}", - "iso_url": "{{user `iso_url`}}", - "name": "centos-7-x86_64", - "output_directory": "img_centos_7_virtualbox", - "shutdown_command": "echo 'packer'|sudo -S /sbin/halt -h -p", - "ssh_handshake_attempts": 50, - "ssh_password": "changeme", - "ssh_port": 22, - "ssh_timeout": "20000s", - "ssh_username": "root", - "type": "virtualbox-iso", - "vboxmanage": [ - [ - "modifyvm", - "{{.Name}}", - "--paravirtprovider", - "kvm" - ], - [ - "modifyvm", - "{{.Name}}", - "--nictype1", - "virtio" - ], - [ - "modifyvm", - "{{.Name}}", - "--memory", - "1024" - ], - [ - "modifyvm", - "{{.Name}}", - "--cpus", - "1" - ] - ], - "virtualbox_version_file": ".vbox_version" - } - ], - "post-processors": [ - { - "type": "vagrant" - } - ], - "provisioners": [ - { - "execute_command": "{{ .Vars }} /bin/sh '{{.Path}}'", - "scripts": [ - "scripts/vagrant.sh" - ], - "type": "shell" - }, - { - "goss_file": "goss.yaml", - "retry_timeout": "5s", - "sleep": "2s", - "tests": [ - "goss/goss.yaml" - ], - "type": "goss" - }, - { - "execute_command": "{{ .Vars }} /bin/sh '{{.Path}}'", - "scripts": [ - "scripts/cleanup.sh", - "scripts/zerodisk.sh" - ], - "type": "shell" - } - ], - "variables": { - "iso_checksum": "b79079ad71cc3c5ceb3561fff348a1b67ee37f71f4cddfec09480d4589c191d6", - "iso_checksum_type ": "sha256", - "iso_url": "http://mirror.net.cen.ct.gov/centos/7.9.2009/isos/x86_64/CentOS-7-x86_64-NetInstall-2009.iso" - } -} - diff --git a/example/scripts/cleanup.sh b/example/scripts/cleanup.sh deleted file mode 100644 index 5025c03..0000000 --- a/example/scripts/cleanup.sh +++ /dev/null @@ -1,11 +0,0 @@ -echo "Cleaning up ..." - -yum -y erase gtk2 libX11 hicolor-icon-theme avahi bitstream-vera-fonts -yum -y clean all -rm -rf /etc/yum.repos.d/{puppetlabs,epel}.repo -rm -rf /etc/yum.repos.d/mysql*.repo -rm -rf VBoxGuestAdditions_*.iso - -# Remove traces of mac address from network configuration -sed -i /HWADDR/d /etc/sysconfig/network-scripts/ifcfg-eth0 -rm -f /etc/udev/rules.d/70-persistent-net.rules diff --git a/example/scripts/vagrant.sh b/example/scripts/vagrant.sh deleted file mode 100644 index a431942..0000000 --- a/example/scripts/vagrant.sh +++ /dev/null @@ -1,31 +0,0 @@ -echo "Configuring vagrant-specific stuff ..." - -# Vagrant specific -date > /etc/vagrant_box_build_time - -# install wget -yum -y install wget - -# disable iptables -/etc/init.d/iptables stop -/sbin/chkconfig iptables off - -# Add vagrant user -/usr/sbin/groupadd vagrant -/usr/sbin/useradd vagrant -g vagrant -G wheel -echo "vagrant"|passwd --stdin vagrant -/bin/sed -i 's/[^\!]requiretty/\!requiretty/' /etc/sudoers -/bin/sed -i 's/^\(Default.*secure_path.*$\)/\1:\/usr\/local\/bin/' /etc/sudoers -echo "vagrant ALL=(ALL) NOPASSWD: ALL" >> /etc/sudoers.d/vagrant -chmod 0440 /etc/sudoers.d/vagrant - -# Speed up ssh connections -/bin/sed -i 's/^#UseDNS.*$/UseDNS no/' /etc/ssh/sshd_config -/bin/sed -i 's/^.*GSSAPIAuthentication.*$/GSSAPIAuthentication no/' /etc/ssh/sshd_config - -# Installing vagrant keys -mkdir -pm 700 /home/vagrant/.ssh -wget --no-check-certificate 'https://raw.githubusercontent.com/mitchellh/vagrant/master/keys/vagrant.pub' -O /home/vagrant/.ssh/authorized_keys -chmod 0600 /home/vagrant/.ssh/authorized_keys -chown -R vagrant:vagrant /home/vagrant/.ssh - \ No newline at end of file diff --git a/example/scripts/zerodisk.sh b/example/scripts/zerodisk.sh deleted file mode 100644 index 37bdb66..0000000 --- a/example/scripts/zerodisk.sh +++ /dev/null @@ -1,5 +0,0 @@ -echo "Zeroing out free space ..." - -# Zero out the free space to save space in the final image: -dd if=/dev/zero of=/EMPTY bs=1M -rm -f /EMPTY diff --git a/examples/build.pkr.hcl b/examples/build.pkr.hcl new file mode 100644 index 0000000..16f804d --- /dev/null +++ b/examples/build.pkr.hcl @@ -0,0 +1,31 @@ +build { + # apply build params against the alpine container + sources = ["docker.linux"] + + # run goss tests using goss provisioner + provisioner "goss" { + + # goss download parameter + installation { + version = "0.4.2" + } + + # goss validate parameter + validate { + goss_file = "./goss_tmpl.yaml" + vars_file = "./vars.yaml" + + vars_inline = { + pkg_installed = true + } + + env_vars = { + curl_installed = false + } + + format = "junit" + format_options = "pretty" + output_file = "test-results.xml" + } + } +} \ No newline at end of file diff --git a/examples/dir/dir2/goss.yaml b/examples/dir/dir2/goss.yaml new file mode 100644 index 0000000..61dabd4 --- /dev/null +++ b/examples/dir/dir2/goss.yaml @@ -0,0 +1,3 @@ +package: + ansible: + installed: true \ No newline at end of file diff --git a/examples/goss_included.yaml b/examples/goss_included.yaml new file mode 100644 index 0000000..3b83229 --- /dev/null +++ b/examples/goss_included.yaml @@ -0,0 +1,3 @@ +package: + telnet: + installed: true \ No newline at end of file diff --git a/examples/goss_tmpl.yaml b/examples/goss_tmpl.yaml new file mode 100644 index 0000000..b02722f --- /dev/null +++ b/examples/goss_tmpl.yaml @@ -0,0 +1,9 @@ +package: + {{ .Vars.pkg }}: + installed: {{ .Vars.pkg_installed }} + curl: + installed: {{ .Env.curl_installed }} + +gossfile: + goss_included.yaml: {} + dir/dir2/goss.yaml: {} \ No newline at end of file diff --git a/examples/packer.pkr.hcl b/examples/packer.pkr.hcl new file mode 100644 index 0000000..3745d27 --- /dev/null +++ b/examples/packer.pkr.hcl @@ -0,0 +1,14 @@ +packer { + required_version = ">= 1.9.0" + + required_plugins { + goss = { + version = "v0.0.1" + source = "github.com/YaleUniversity/goss" + } + docker = { + source = "github.com/hashicorp/docker" + version = "v1.0.10" + } + } +} diff --git a/examples/source.pkr.hcl b/examples/source.pkr.hcl new file mode 100644 index 0000000..b4c9754 --- /dev/null +++ b/examples/source.pkr.hcl @@ -0,0 +1,5 @@ +# fetch a normal alpine container and export the image as alpine.tar +source "docker" "linux" { + image = "alpine" + export_path = "linux.tar" +} \ No newline at end of file diff --git a/examples/vars.yaml b/examples/vars.yaml new file mode 100644 index 0000000..b1fbf89 --- /dev/null +++ b/examples/vars.yaml @@ -0,0 +1 @@ +pkg: terraform \ No newline at end of file diff --git a/go.mod b/go.mod index d5cd027..76c8d21 100644 --- a/go.mod +++ b/go.mod @@ -1,26 +1,115 @@ module github.com/YaleUniversity/packer-provisioner-goss -go 1.21.0 +go 1.22 -toolchain go1.21.1 +toolchain go1.22.6 require ( + github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d + github.com/daixiang0/gci v0.13.4 + github.com/golangci/golangci-lint v1.59.1 + github.com/goss-org/goss v0.4.9 github.com/hashicorp/hcl/v2 v2.22.0 github.com/hashicorp/packer-plugin-sdk v0.5.4 + github.com/stretchr/testify v1.9.0 github.com/zclconf/go-cty v1.14.2 + gopkg.in/yaml.v2 v2.4.0 + gotest.tools/gotestsum v1.12.0 + mvdan.cc/gofumpt v0.6.0 ) require ( + 4d63.com/gocheckcompilerdirectives v1.2.1 // indirect + 4d63.com/gochecknoglobals v0.2.1 // indirect + dario.cat/mergo v1.0.1 // indirect + github.com/4meepo/tagalign v1.3.4 // indirect + github.com/Abirdcfly/dupword v0.0.14 // indirect + github.com/Antonboom/errname v0.1.13 // indirect + github.com/Antonboom/nilnil v0.1.9 // indirect + github.com/Antonboom/testifylint v1.3.1 // indirect + github.com/BurntSushi/toml v1.4.0 // indirect + github.com/Crocmagnon/fatcontext v0.2.2 // indirect + github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 // indirect + github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0 // indirect + github.com/Masterminds/goutils v1.1.1 // indirect + github.com/Masterminds/semver/v3 v3.3.0 // indirect + github.com/Masterminds/sprig/v3 v3.3.0 // indirect + github.com/OpenPeeDeeP/depguard/v2 v2.2.0 // indirect + github.com/achanda/go-sysctl v0.0.0-20160222034550-6be7678c45d2 // indirect github.com/agext/levenshtein v1.2.3 // indirect + github.com/alecthomas/go-check-sumtype v0.1.4 // indirect + github.com/alexkohler/nakedret/v2 v2.0.4 // indirect + github.com/alexkohler/prealloc v1.0.0 // indirect + github.com/alingse/asasalint v0.0.11 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-metrics v0.4.1 // indirect + github.com/armon/go-radix v1.0.0 // indirect + github.com/ashanbrown/forbidigo v1.6.0 // indirect + github.com/ashanbrown/makezero v1.1.1 // indirect github.com/aws/aws-sdk-go v1.44.114 // indirect + github.com/beorn7/perks v1.0.1 // indirect github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect + github.com/bgentry/speakeasy v0.1.0 // indirect + github.com/bitfield/gotestdox v0.2.2 // indirect + github.com/bkielbasa/cyclop v1.2.1 // indirect + github.com/blang/semver/v4 v4.0.0 // indirect + github.com/blizzy78/varnamelen v0.8.0 // indirect + github.com/bombsimon/wsl/v4 v4.2.1 // indirect + github.com/breml/bidichk v0.2.7 // indirect + github.com/breml/errchkjson v0.3.6 // indirect + github.com/butuzov/ireturn v0.3.0 // indirect + github.com/butuzov/mirror v1.2.0 // indirect + github.com/catenacyber/perfsprint v0.7.1 // indirect + github.com/ccojocar/zxcvbn-go v1.0.2 // indirect github.com/cenkalti/backoff/v3 v3.2.2 // indirect - github.com/fatih/color v1.16.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/charithe/durationcheck v0.0.10 // indirect + github.com/chavacava/garif v0.1.0 // indirect + github.com/cheekybits/genny v1.0.0 // indirect + github.com/ckaznocha/intrange v0.1.2 // indirect + github.com/curioswitch/go-reassign v0.2.0 // indirect + github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect + github.com/denis-tingaikin/go-header v0.5.0 // indirect + github.com/dnephin/pflag v1.0.7 // indirect + github.com/ettle/strcase v0.2.0 // indirect + github.com/fatih/camelcase v1.0.0 // indirect + github.com/fatih/color v1.17.0 // indirect + github.com/fatih/structtag v1.2.0 // indirect + github.com/firefart/nonamedreturns v1.0.5 // indirect + github.com/fsnotify/fsnotify v1.7.0 // indirect + github.com/fzipp/gocyclo v0.6.0 // indirect + github.com/ghostiam/protogetter v0.3.6 // indirect + github.com/go-critic/go-critic v0.11.4 // indirect github.com/go-jose/go-jose/v4 v4.0.1 // indirect - github.com/google/uuid v1.4.0 // indirect + github.com/go-toolsmith/astcast v1.1.0 // indirect + github.com/go-toolsmith/astcopy v1.1.0 // indirect + github.com/go-toolsmith/astequal v1.2.0 // indirect + github.com/go-toolsmith/astfmt v1.1.0 // indirect + github.com/go-toolsmith/astp v1.1.0 // indirect + github.com/go-toolsmith/strparse v1.1.0 // indirect + github.com/go-toolsmith/typep v1.1.0 // indirect + github.com/go-viper/mapstructure/v2 v2.0.0 // indirect + github.com/go-xmlfmt/xmlfmt v1.1.2 // indirect + github.com/gobwas/glob v0.2.3 // indirect + github.com/gofrs/flock v0.8.1 // indirect + github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a // indirect + github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e // indirect + github.com/golangci/misspell v0.6.0 // indirect + github.com/golangci/modinfo v0.3.4 // indirect + github.com/golangci/plugin-module-register v0.1.1 // indirect + github.com/golangci/revgrep v0.5.3 // indirect + github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/gordonklaus/ineffassign v0.1.0 // indirect + github.com/goss-org/GOnetstat v0.0.0-20230101144325-22be0bd9e64d // indirect + github.com/goss-org/go-ps v0.0.0-20230609005227-7b318e6a56e5 // indirect + github.com/gostaticanalysis/analysisutil v0.7.1 // indirect + github.com/gostaticanalysis/comment v1.4.2 // indirect + github.com/gostaticanalysis/forcetypeassert v0.1.0 // indirect + github.com/gostaticanalysis/nilerr v0.1.1 // indirect github.com/hashicorp/consul/api v1.25.1 // indirect github.com/hashicorp/errwrap v1.1.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect @@ -28,41 +117,154 @@ require ( github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-immutable-radix v1.3.1 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect - github.com/hashicorp/go-retryablehttp v0.7.6 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-rootcerts v1.0.2 // indirect github.com/hashicorp/go-safetemp v1.0.0 // indirect github.com/hashicorp/go-secure-stdlib/parseutil v0.1.6 // indirect github.com/hashicorp/go-secure-stdlib/strutil v0.1.2 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect - github.com/hashicorp/go-version v1.6.0 // indirect + github.com/hashicorp/go-version v1.7.0 // indirect github.com/hashicorp/golang-lru v0.5.4 // indirect github.com/hashicorp/hcl v1.0.0 // indirect + github.com/hashicorp/logutils v1.0.0 // indirect github.com/hashicorp/serf v0.10.1 // indirect github.com/hashicorp/vault/api v1.14.0 // indirect github.com/hashicorp/yamux v0.1.1 // indirect + github.com/hexops/gotextdiff v1.0.3 // indirect + github.com/huandu/xstrings v1.5.0 // indirect + github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 // indirect + github.com/jgautheron/goconst v1.7.1 // indirect + github.com/jingyugao/rowserrcheck v1.1.1 // indirect + github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af // indirect + github.com/jjti/go-spancheck v0.6.1 // indirect github.com/jmespath/go-jmespath v0.4.0 // indirect + github.com/julz/importas v0.1.0 // indirect + github.com/karamaru-alpha/copyloopvar v1.1.0 // indirect + github.com/kisielk/errcheck v1.7.0 // indirect + github.com/kkHAIKE/contextcheck v1.1.5 // indirect github.com/klauspost/compress v1.15.9 // indirect + github.com/kulti/thelper v0.6.3 // indirect + github.com/kunwardeep/paralleltest v1.0.10 // indirect + github.com/kyoh86/exportloopref v0.1.11 // indirect + github.com/lasiar/canonicalheader v1.1.1 // indirect + github.com/ldez/gomoddirectives v0.2.4 // indirect + github.com/ldez/tagliatelle v0.5.0 // indirect + github.com/leonklingele/grouper v1.1.2 // indirect + github.com/lufeee/execinquery v1.2.1 // indirect + github.com/macabu/inamedparam v0.1.3 // indirect + github.com/magiconair/properties v1.8.6 // indirect + github.com/maratori/testableexamples v1.0.0 // indirect + github.com/maratori/testpackage v1.1.1 // indirect + github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 // indirect github.com/mattn/go-colorable v0.1.13 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.9 // indirect + github.com/mgechev/revive v1.3.7 // indirect + github.com/miekg/dns v1.1.61 // indirect + github.com/mitchellh/cli v1.1.5 // indirect + github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.1 // indirect github.com/mitchellh/iochan v1.0.0 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/mitchellh/reflectwalk v1.0.0 // indirect + github.com/mitchellh/reflectwalk v1.0.2 // indirect + github.com/moby/sys/mountinfo v0.7.1 // indirect + github.com/moricho/tparallel v0.3.1 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/nakabonne/nestif v0.3.1 // indirect + github.com/nishanths/exhaustive v0.12.0 // indirect + github.com/nishanths/predeclared v0.2.2 // indirect + github.com/nunnatsa/ginkgolinter v0.16.2 // indirect + github.com/oleiade/reflections v1.0.1 // indirect + github.com/olekukonko/tablewriter v0.0.5 // indirect + github.com/onsi/gomega v1.33.1 // indirect + github.com/patrickmn/go-cache v2.1.0+incompatible // indirect + github.com/pelletier/go-toml v1.9.5 // indirect + github.com/pelletier/go-toml/v2 v2.2.2 // indirect + github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e // indirect + github.com/pkg/errors v0.9.1 // indirect + github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect + github.com/polyfloyd/go-errorlint v1.5.2 // indirect + github.com/posener/complete v1.2.3 // indirect + github.com/prometheus/client_golang v1.19.1 // indirect + github.com/prometheus/client_model v0.6.1 // indirect + github.com/prometheus/common v0.55.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect + github.com/quasilyte/go-ruleguard v0.4.2 // indirect + github.com/quasilyte/go-ruleguard/dsl v0.3.22 // indirect + github.com/quasilyte/gogrep v0.5.0 // indirect + github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 // indirect + github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 // indirect + github.com/ryancurrah/gomodguard v1.3.2 // indirect + github.com/ryanrolds/sqlclosecheck v0.5.1 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect + github.com/samber/lo v1.46.0 // indirect + github.com/sanposhiho/wastedassign/v2 v2.0.7 // indirect + github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 // indirect + github.com/sashamelentyev/interfacebloat v1.1.0 // indirect + github.com/sashamelentyev/usestdlibvars v1.26.0 // indirect + github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 // indirect + github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c // indirect + github.com/shopspring/decimal v1.4.0 // indirect + github.com/sirupsen/logrus v1.9.3 // indirect + github.com/sivchari/containedctx v1.0.3 // indirect + github.com/sivchari/tenv v1.7.1 // indirect + github.com/sonatard/noctx v0.0.2 // indirect + github.com/sourcegraph/go-diff v0.7.0 // indirect + github.com/spf13/afero v1.11.0 // indirect + github.com/spf13/cast v1.7.0 // indirect + github.com/spf13/cobra v1.7.0 // indirect + github.com/spf13/jwalterweatherman v1.1.0 // indirect + github.com/spf13/pflag v1.0.5 // indirect + github.com/spf13/viper v1.12.0 // indirect + github.com/ssgreg/nlreturn/v2 v2.2.1 // indirect + github.com/stbenjam/no-sprintf-host-port v0.1.1 // indirect + github.com/stretchr/objx v0.5.2 // indirect + github.com/subosito/gotenv v1.4.1 // indirect + github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c // indirect + github.com/tdakkota/asciicheck v0.2.0 // indirect + github.com/tetafro/godot v1.4.16 // indirect + github.com/tidwall/gjson v1.17.1 // indirect + github.com/tidwall/match v1.1.1 // indirect + github.com/tidwall/pretty v1.2.1 // indirect + github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 // indirect + github.com/timonwong/loggercheck v0.9.4 // indirect + github.com/tomarrell/wrapcheck/v2 v2.8.3 // indirect + github.com/tommy-muehle/go-mnd/v2 v2.5.1 // indirect github.com/ugorji/go/codec v1.2.6 // indirect github.com/ulikunitz/xz v0.5.10 // indirect - golang.org/x/crypto v0.23.0 // indirect - golang.org/x/exp v0.0.0-20230321023759-10a507213a29 // indirect - golang.org/x/mod v0.13.0 // indirect - golang.org/x/net v0.25.0 // indirect - golang.org/x/sys v0.20.0 // indirect - golang.org/x/text v0.15.0 // indirect - golang.org/x/time v0.3.0 // indirect - golang.org/x/tools v0.14.0 // indirect - gopkg.in/yaml.v2 v2.3.0 // indirect + github.com/ultraware/funlen v0.1.0 // indirect + github.com/ultraware/whitespace v0.1.1 // indirect + github.com/uudashr/gocognit v1.1.2 // indirect + github.com/xen0n/gosmopolitan v1.2.2 // indirect + github.com/yagipy/maintidx v1.0.0 // indirect + github.com/yeya24/promlinter v0.3.0 // indirect + github.com/ykadowak/zerologlint v0.1.5 // indirect + gitlab.com/bosi/decorder v0.4.2 // indirect + go-simpler.org/musttag v0.12.2 // indirect + go-simpler.org/sloglint v0.7.1 // indirect + go.uber.org/atomic v1.7.0 // indirect + go.uber.org/automaxprocs v1.5.3 // indirect + go.uber.org/multierr v1.6.0 // indirect + go.uber.org/zap v1.24.0 // indirect + golang.org/x/crypto v0.26.0 // indirect + golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 // indirect + golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f // indirect + golang.org/x/mod v0.19.0 // indirect + golang.org/x/net v0.27.0 // indirect + golang.org/x/sync v0.8.0 // indirect + golang.org/x/sys v0.23.0 // indirect + golang.org/x/term v0.23.0 // indirect + golang.org/x/text v0.17.0 // indirect + golang.org/x/time v0.5.0 // indirect + golang.org/x/tools v0.23.0 // indirect + google.golang.org/protobuf v1.34.2 // indirect + gopkg.in/ini.v1 v1.67.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect + honnef.co/go/tools v0.4.7 // indirect + mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f // indirect ) replace github.com/zclconf/go-cty => github.com/nywilken/go-cty v1.13.3 // added by packer-sdc fix as noted in github.com/hashicorp/packer-plugin-sdk/issues/187 diff --git a/go.sum b/go.sum index eb6c419..fc154b7 100644 --- a/go.sum +++ b/go.sum @@ -1,10 +1,60 @@ +4d63.com/gocheckcompilerdirectives v1.2.1 h1:AHcMYuw56NPjq/2y615IGg2kYkBdTvOaojYCBcRE7MA= +4d63.com/gocheckcompilerdirectives v1.2.1/go.mod h1:yjDJSxmDTtIHHCqX0ufRYZDL6vQtMG7tJdKVeWwsqvs= +4d63.com/gochecknoglobals v0.2.1 h1:1eiorGsgHOFOuoOiJDy2psSrQbRdIHrlge0IJIkUgDc= +4d63.com/gochecknoglobals v0.2.1/go.mod h1:KRE8wtJB3CXCsb1xy421JfTHIIbmT3U5ruxw2Qu8fSU= +dario.cat/mergo v1.0.1 h1:Ra4+bf83h2ztPIQYNP99R6m+Y7KfnARDfID+a+vLl4s= +dario.cat/mergo v1.0.1/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= +github.com/4meepo/tagalign v1.3.4 h1:P51VcvBnf04YkHzjfclN6BbsopfJR5rxs1n+5zHt+w8= +github.com/4meepo/tagalign v1.3.4/go.mod h1:M+pnkHH2vG8+qhE5bVc/zeP7HS/j910Fwa9TUSyZVI0= +github.com/Abirdcfly/dupword v0.0.14 h1:3U4ulkc8EUo+CaT105/GJ1BQwtgyj6+VaBVbAX11Ba8= +github.com/Abirdcfly/dupword v0.0.14/go.mod h1:VKDAbxdY8YbKUByLGg8EETzYSuC4crm9WwI6Y3S0cLI= +github.com/Antonboom/errname v0.1.13 h1:JHICqsewj/fNckzrfVSe+T33svwQxmjC+1ntDsHOVvM= +github.com/Antonboom/errname v0.1.13/go.mod h1:uWyefRYRN54lBg6HseYCFhs6Qjcy41Y3Jl/dVhA87Ns= +github.com/Antonboom/nilnil v0.1.9 h1:eKFMejSxPSA9eLSensFmjW2XTgTwJMjZ8hUHtV4s/SQ= +github.com/Antonboom/nilnil v0.1.9/go.mod h1:iGe2rYwCq5/Me1khrysB4nwI7swQvjclR8/YRPl5ihQ= +github.com/Antonboom/testifylint v1.3.1 h1:Uam4q1Q+2b6H7gvk9RQFw6jyVDdpzIirFOOrbs14eG4= +github.com/Antonboom/testifylint v1.3.1/go.mod h1:NV0hTlteCkViPW9mSR4wEMfwp+Hs1T3dY60bkvSfhpM= +github.com/BurntSushi/toml v1.4.0 h1:kuoIxZQy2WRRk1pttg9asf+WVv6tWQuBNVmK8+nqPr0= +github.com/BurntSushi/toml v1.4.0/go.mod h1:ukJfTF/6rtPPRCnwkur4qwRxa8vTRFBF0uk2lLoLwho= +github.com/Crocmagnon/fatcontext v0.2.2 h1:OrFlsDdOj9hW/oBEJBNSuH7QWf+E9WPVHw+x52bXVbk= +github.com/Crocmagnon/fatcontext v0.2.2/go.mod h1:WSn/c/+MMNiD8Pri0ahRj0o9jVpeowzavOQplBJw6u0= github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24 h1:sHglBQTwgx+rWPdisA5ynNEsoARbiCBOyGcJM4/OzsM= +github.com/Djarvur/go-err113 v0.0.0-20210108212216-aea10b59be24/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0 h1:sATXp1x6/axKxz2Gjxv8MALP0bXaNRfQinEwyfMcx8c= +github.com/GaijinEntertainment/go-exhaustruct/v3 v3.2.0/go.mod h1:Nl76DrGNJTA1KJ0LePKBw/vznBX1EHbAZX8mwjR82nI= +github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI= +github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU= +github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs= +github.com/Masterminds/semver/v3 v3.3.0 h1:B8LGeaivUe71a5qox1ICM/JLl0NqZSW5CHyL+hmvYS0= +github.com/Masterminds/semver/v3 v3.3.0/go.mod h1:4V+yj/TJE1HU9XfppCwVMZq3I84lprf4nC11bSS5beM= +github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk= +github.com/Masterminds/sprig/v3 v3.3.0 h1:mQh0Yrg1XPo6vjYXgtf5OtijNAKJRNcTdOOGZe3tPhs= +github.com/Masterminds/sprig/v3 v3.3.0/go.mod h1:Zy1iXRYNqNLUolqCpL4uhk6SHUMAOSCzdgBfDb35Lz0= +github.com/OpenPeeDeeP/depguard/v2 v2.2.0 h1:vDfG60vDtIuf0MEOhmLlLLSzqaRM8EMcgJPdp74zmpA= +github.com/OpenPeeDeeP/depguard/v2 v2.2.0/go.mod h1:CIzddKRvLBC4Au5aYP/i3nyaWQ+ClszLIuVocRiCYFQ= +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d h1:licZJFw2RwpHMqeKTCYkitsPqHNxTmd4SNR5r94FGM8= +github.com/acarl005/stripansi v0.0.0-20180116102854-5a71ef0e047d/go.mod h1:asat636LX7Bqt5lYEZ27JNDcqxfjdBQuJ/MM4CN/Lzo= +github.com/achanda/go-sysctl v0.0.0-20160222034550-6be7678c45d2 h1:NYoPVh1XuUB5VBWLXRKoqzQhl4bajIxh+XuURbJ0uwc= +github.com/achanda/go-sysctl v0.0.0-20160222034550-6be7678c45d2/go.mod h1:DCNKSpXhum14Y258jSbRmJvcesbzEdBPincz7yJUx3k= github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo= github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= +github.com/alecthomas/assert/v2 v2.2.2 h1:Z/iVC0xZfWTaFNE6bA3z07T86hd45Xe2eLt6WVy2bbk= +github.com/alecthomas/assert/v2 v2.2.2/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= +github.com/alecthomas/go-check-sumtype v0.1.4 h1:WCvlB3l5Vq5dZQTFmodqL2g68uHiSwwlWcT5a2FGK0c= +github.com/alecthomas/go-check-sumtype v0.1.4/go.mod h1:WyYPfhfkdhyrdaligV6svFopZV8Lqdzn5pyVBaV6jhQ= +github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= +github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= +github.com/alexkohler/nakedret/v2 v2.0.4 h1:yZuKmjqGi0pSmjGpOC016LtPJysIL0WEUiaXW5SUnNg= +github.com/alexkohler/nakedret/v2 v2.0.4/go.mod h1:bF5i0zF2Wo2o4X4USt9ntUWve6JbFv02Ff4vlkmS/VU= +github.com/alexkohler/prealloc v1.0.0 h1:Hbq0/3fJPQhNkN0dR95AVrr6R7tou91y0uHG5pOcUuw= +github.com/alexkohler/prealloc v1.0.0/go.mod h1:VetnK3dIgFBBKmg0YnD9F9x6Icjd+9cvfHR56wJVlKE= +github.com/alingse/asasalint v0.0.11 h1:SFwnQXJ49Kx/1GghOFz1XGqHYKp21Kq1nHad/0WQRnw= +github.com/alingse/asasalint v0.0.11/go.mod h1:nCaoMhw7a9kSJObvQyVzNTPBDbNpdocqrSP7t/cW5+I= github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw= github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= @@ -14,52 +64,201 @@ github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmV github.com/armon/go-metrics v0.4.1 h1:hR91U9KYmb6bLBYLQjyM+3j+rcd/UhE+G78SFnF8gJA= github.com/armon/go-metrics v0.4.1/go.mod h1:E6amYzXo6aW1tqzoZGT755KkbgrJsSdpwZ+3JqfkOG4= github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI= github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8= +github.com/ashanbrown/forbidigo v1.6.0 h1:D3aewfM37Yb3pxHujIPSpTf6oQk9sc9WZi8gerOIVIY= +github.com/ashanbrown/forbidigo v1.6.0/go.mod h1:Y8j9jy9ZYAEHXdu723cUlraTqbzjKF1MUyfOKL+AjcU= +github.com/ashanbrown/makezero v1.1.1 h1:iCQ87C0V0vSyO+M9E/FZYbu65auqH0lnsOkf5FcB28s= +github.com/ashanbrown/makezero v1.1.1/go.mod h1:i1bJLCRSCHOcOa9Y6MyF2FTfMZMFdHvxKHxgO5Z1axI= github.com/aws/aws-sdk-go v1.44.114 h1:plIkWc/RsHr3DXBj4MEw9sEW4CcL/e2ryokc+CKyq1I= github.com/aws/aws-sdk-go v1.44.114/go.mod h1:y4AeaBuwd2Lk+GepC1E9v0qOiTws0MIWAX4oIKwKHZo= +github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLju8= +github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= +github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas= github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4= +github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQkY= github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= +github.com/bitfield/gotestdox v0.2.2 h1:x6RcPAbBbErKLnapz1QeAlf3ospg8efBsedU93CDsnE= +github.com/bitfield/gotestdox v0.2.2/go.mod h1:D+gwtS0urjBrzguAkTM2wodsTQYFHdpx8eqRJ3N+9pY= +github.com/bkielbasa/cyclop v1.2.1 h1:AeF71HZDob1P2/pRm1so9cd1alZnrpyc4q2uP2l0gJY= +github.com/bkielbasa/cyclop v1.2.1/go.mod h1:K/dT/M0FPAiYjBgQGau7tz+3TMh4FWAEqlMhzFWCrgM= +github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM= +github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ= +github.com/blizzy78/varnamelen v0.8.0 h1:oqSblyuQvFsW1hbBHh1zfwrKe3kcSj0rnXkKzsQ089M= +github.com/blizzy78/varnamelen v0.8.0/go.mod h1:V9TzQZ4fLJ1DSrjVDfl89H7aMnTvKkApdHeyESmyR7k= +github.com/bombsimon/wsl/v4 v4.2.1 h1:Cxg6u+XDWff75SIFFmNsqnIOgob+Q9hG6y/ioKbRFiM= +github.com/bombsimon/wsl/v4 v4.2.1/go.mod h1:Xu/kDxGZTofQcDGCtQe9KCzhHphIe0fDuyWTxER9Feo= +github.com/breml/bidichk v0.2.7 h1:dAkKQPLl/Qrk7hnP6P+E0xOodrq8Us7+U0o4UBOAlQY= +github.com/breml/bidichk v0.2.7/go.mod h1:YodjipAGI9fGcYM7II6wFvGhdMYsC5pHDlGzqvEW3tQ= +github.com/breml/errchkjson v0.3.6 h1:VLhVkqSBH96AvXEyclMR37rZslRrY2kcyq+31HCsVrA= +github.com/breml/errchkjson v0.3.6/go.mod h1:jhSDoFheAF2RSDOlCfhHO9KqhZgAYLyvHe7bRCX8f/U= +github.com/butuzov/ireturn v0.3.0 h1:hTjMqWw3y5JC3kpnC5vXmFJAWI/m31jaCYQqzkS6PL0= +github.com/butuzov/ireturn v0.3.0/go.mod h1:A09nIiwiqzN/IoVo9ogpa0Hzi9fex1kd9PSD6edP5ZA= +github.com/butuzov/mirror v1.2.0 h1:9YVK1qIjNspaqWutSv8gsge2e/Xpq1eqEkslEUHy5cs= +github.com/butuzov/mirror v1.2.0/go.mod h1:DqZZDtzm42wIAIyHXeN8W/qb1EPlb9Qn/if9icBOpdQ= +github.com/catenacyber/perfsprint v0.7.1 h1:PGW5G/Kxn+YrN04cRAZKC+ZuvlVwolYMrIyyTJ/rMmc= +github.com/catenacyber/perfsprint v0.7.1/go.mod h1:/wclWYompEyjUD2FuIIDVKNkqz7IgBIWXIH3V0Zol50= +github.com/ccojocar/zxcvbn-go v1.0.2 h1:na/czXU8RrhXO4EZme6eQJLR4PzcGsahsBOAwU6I3Vg= +github.com/ccojocar/zxcvbn-go v1.0.2/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60= github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M= github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/charithe/durationcheck v0.0.10 h1:wgw73BiocdBDQPik+zcEoBG/ob8uyBHf2iyoHGPf5w4= +github.com/charithe/durationcheck v0.0.10/go.mod h1:bCWXb7gYRysD1CU3C+u4ceO49LoGOY1C1L6uouGNreQ= +github.com/chavacava/garif v0.1.0 h1:2JHa3hbYf5D9dsgseMKAmc/MZ109otzgNFk5s87H9Pc= +github.com/chavacava/garif v0.1.0/go.mod h1:XMyYCkEL58DF0oyW4qDjjnPWONs2HBqYKI+UIPD+Gww= +github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE= +github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ= github.com/circonus-labs/circonus-gometrics v2.3.1+incompatible/go.mod h1:nmEj6Dob7S7YxXgwXpfOuvO54S+tGdZdw9fuRZt25Ag= github.com/circonus-labs/circonusllhist v0.1.3/go.mod h1:kMXHVDlOchFAehlya5ePtbp5jckzBHf4XRpQvBOLI+I= +github.com/ckaznocha/intrange v0.1.2 h1:3Y4JAxcMntgb/wABQ6e8Q8leMd26JbX2790lIss9MTI= +github.com/ckaznocha/intrange v0.1.2/go.mod h1:RWffCw/vKBwHeOEwWdCikAtY0q4gGt8VhJZEEA5n+RE= +github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= +github.com/curioswitch/go-reassign v0.2.0 h1:G9UZyOcpk/d7Gd6mqYgd8XYWFMw/znxwGDUstnC9DIo= +github.com/curioswitch/go-reassign v0.2.0/go.mod h1:x6OpXuWvgfQaMGks2BZybTngWjT84hqJfKoO8Tt/Roc= +github.com/daixiang0/gci v0.13.4 h1:61UGkmpoAcxHM2hhNkZEf5SzwQtWJXTSws7jaPyqwlw= +github.com/daixiang0/gci v0.13.4/go.mod h1:12etP2OniiIdP4q+kjUGrC/rUagga7ODbqsom5Eo5Yk= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM= github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/denis-tingaikin/go-header v0.5.0 h1:SRdnP5ZKvcO9KKRP1KJrhFR3RrlGuD+42t4429eC9k8= +github.com/denis-tingaikin/go-header v0.5.0/go.mod h1:mMenU5bWrok6Wl2UsZjy+1okegmwQ3UgWl4V1D8gjlY= +github.com/dnephin/pflag v1.0.7 h1:oxONGlWxhmUct0YzKTgrpQv9AUA1wtPBn7zuSjJqptk= +github.com/dnephin/pflag v1.0.7/go.mod h1:uxE91IoWURlOiTUIA8Mq5ZZkAv3dPUfZNaT80Zm7OQE= +github.com/ettle/strcase v0.2.0 h1:fGNiVF21fHXpX1niBgk0aROov1LagYsOwV/xqKDKR/Q= +github.com/ettle/strcase v0.2.0/go.mod h1:DajmHElDSaX76ITe3/VHVyMin4LWSJN5Z909Wp+ED1A= +github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= +github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw= github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= +github.com/fatih/color v1.17.0 h1:GlRw1BRJxkpqUCBKzKOw098ed57fEsKeNjpTe3cSjK4= +github.com/fatih/color v1.17.0/go.mod h1:YZ7TlrGPkiz6ku9fK3TLD/pl3CpsiFyu8N92HLgmosI= +github.com/fatih/structtag v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4= +github.com/fatih/structtag v1.2.0/go.mod h1:mBJUNpUnHmRKrKlQQlmCrh5PuhftFbNv8Ys4/aAZl94= +github.com/firefart/nonamedreturns v1.0.5 h1:tM+Me2ZaXs8tfdDw3X6DOX++wMCOqzYUho6tUTYIdRA= +github.com/firefart/nonamedreturns v1.0.5/go.mod h1:gHJjDqhGM4WyPt639SOZs+G89Ko7QKH5R5BhnO6xJhw= +github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= +github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= +github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= +github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM= +github.com/fzipp/gocyclo v0.6.0 h1:lsblElZG7d3ALtGMx9fmxeTKZaLLpU8mET09yN4BBLo= +github.com/fzipp/gocyclo v0.6.0/go.mod h1:rXPyn8fnlpa0R2csP/31uerbiVBugk5whMdlyaLkLoA= +github.com/ghostiam/protogetter v0.3.6 h1:R7qEWaSgFCsy20yYHNIJsU9ZOb8TziSRRxuAOTVKeOk= +github.com/ghostiam/protogetter v0.3.6/go.mod h1:7lpeDnEJ1ZjL/YtyoN99ljO4z0pd3H0d18/t2dPBxHw= +github.com/go-critic/go-critic v0.11.4 h1:O7kGOCx0NDIni4czrkRIXTnit0mkyKOCePh3My6OyEU= +github.com/go-critic/go-critic v0.11.4/go.mod h1:2QAdo4iuLik5S9YG0rT4wcZ8QxwHYkrr6/2MWAiv/vc= github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk= +github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= +github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/go-toolsmith/astcast v1.1.0 h1:+JN9xZV1A+Re+95pgnMgDboWNVnIMMQXwfBwLRPgSC8= +github.com/go-toolsmith/astcast v1.1.0/go.mod h1:qdcuFWeGGS2xX5bLM/c3U9lewg7+Zu4mr+xPwZIB4ZU= +github.com/go-toolsmith/astcopy v1.1.0 h1:YGwBN0WM+ekI/6SS6+52zLDEf8Yvp3n2seZITCUBt5s= +github.com/go-toolsmith/astcopy v1.1.0/go.mod h1:hXM6gan18VA1T/daUEHCFcYiW8Ai1tIwIzHY6srfEAw= +github.com/go-toolsmith/astequal v1.0.3/go.mod h1:9Ai4UglvtR+4up+bAD4+hCj7iTo4m/OXVTSLnCyTAx4= +github.com/go-toolsmith/astequal v1.1.0/go.mod h1:sedf7VIdCL22LD8qIvv7Nn9MuWJruQA/ysswh64lffQ= +github.com/go-toolsmith/astequal v1.2.0 h1:3Fs3CYZ1k9Vo4FzFhwwewC3CHISHDnVUPC4x0bI2+Cw= +github.com/go-toolsmith/astequal v1.2.0/go.mod h1:c8NZ3+kSFtFY/8lPso4v8LuJjdJiUFVnSuU3s0qrrDY= +github.com/go-toolsmith/astfmt v1.1.0 h1:iJVPDPp6/7AaeLJEruMsBUlOYCmvg0MoCfJprsOmcco= +github.com/go-toolsmith/astfmt v1.1.0/go.mod h1:OrcLlRwu0CuiIBp/8b5PYF9ktGVZUjlNMV634mhwuQ4= +github.com/go-toolsmith/astp v1.1.0 h1:dXPuCl6u2llURjdPLLDxJeZInAeZ0/eZwFJmqZMnpQA= +github.com/go-toolsmith/astp v1.1.0/go.mod h1:0T1xFGz9hicKs8Z5MfAqSUitoUYS30pDMsRVIDHs8CA= +github.com/go-toolsmith/pkgload v1.2.2 h1:0CtmHq/02QhxcF7E9N5LIFcYFsMR5rdovfqTtRKkgIk= +github.com/go-toolsmith/pkgload v1.2.2/go.mod h1:R2hxLNRKuAsiXCo2i5J6ZQPhnPMOVtU+f0arbFPWCus= +github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8= +github.com/go-toolsmith/strparse v1.1.0 h1:GAioeZUK9TGxnLS+qfdqNbA4z0SSm5zVNtCQiyP2Bvw= +github.com/go-toolsmith/strparse v1.1.0/go.mod h1:7ksGy58fsaQkGQlY8WVoBFNyEPMGuJin1rfoPS4lBSQ= +github.com/go-toolsmith/typep v1.1.0 h1:fIRYDyF+JywLfqzyhdiHzRop/GQDxxNhLGQ6gFUNHus= +github.com/go-toolsmith/typep v1.1.0/go.mod h1:fVIw+7zjdsMxDA3ITWnH1yOiw1rnTQKCsF/sk2H/qig= +github.com/go-viper/mapstructure/v2 v2.0.0 h1:dhn8MZ1gZ0mzeodTG3jt5Vj/o87xZKuNAprG2mQfMfc= +github.com/go-viper/mapstructure/v2 v2.0.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM= +github.com/go-xmlfmt/xmlfmt v1.1.2 h1:Nea7b4icn8s57fTx1M5AI4qQT5HEM3rVUO8MuE6g80U= +github.com/go-xmlfmt/xmlfmt v1.1.2/go.mod h1:aUCEOzzezBEjDBbFBoSiya/gduyIiWYRP6CnSFIV8AM= +github.com/gobwas/glob v0.2.3 h1:A4xDbljILXROh+kObIiy5kIaPYD8e96x1tgBhUI5J+Y= +github.com/gobwas/glob v0.2.3/go.mod h1:d3Ez4x06l9bZtSvzIay5+Yzi0fmZzPgnTbPcKjJAkT8= +github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw= +github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a h1:w8hkcTqaFpzKqonE9uMCefW1WDie15eSP/4MssdenaM= +github.com/golangci/dupl v0.0.0-20180902072040-3e9179ac440a/go.mod h1:ryS0uhF+x9jgbj/N71xsEqODy9BN81/GonCZiOzirOk= +github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e h1:ULcKCDV1LOZPFxGZaA6TlQbiM3J2GCPnkx/bGF6sX/g= +github.com/golangci/gofmt v0.0.0-20231018234816-f50ced29576e/go.mod h1:Pm5KhLPA8gSnQwrQ6ukebRcapGb/BG9iUkdaiCcGHJM= +github.com/golangci/golangci-lint v1.59.1 h1:CRRLu1JbhK5avLABFJ/OHVSQ0Ie5c4ulsOId1h3TTks= +github.com/golangci/golangci-lint v1.59.1/go.mod h1:jX5Oif4C7P0j9++YB2MMJmoNrb01NJ8ITqKWNLewThg= +github.com/golangci/misspell v0.6.0 h1:JCle2HUTNWirNlDIAUO44hUsKhOFqGPoC4LZxlaSXDs= +github.com/golangci/misspell v0.6.0/go.mod h1:keMNyY6R9isGaSAu+4Q8NMBwMPkh15Gtc8UCVoDtAWo= +github.com/golangci/modinfo v0.3.4 h1:oU5huX3fbxqQXdfspamej74DFX0kyGLkw1ppvXoJ8GA= +github.com/golangci/modinfo v0.3.4/go.mod h1:wytF1M5xl9u0ij8YSvhkEVPP3M5Mc7XLl1pxH3B2aUM= +github.com/golangci/plugin-module-register v0.1.1 h1:TCmesur25LnyJkpsVrupv1Cdzo+2f7zX0H6Jkw1Ol6c= +github.com/golangci/plugin-module-register v0.1.1/go.mod h1:TTpqoB6KkwOJMV8u7+NyXMrkwwESJLOkfl9TxR1DGFc= +github.com/golangci/revgrep v0.5.3 h1:3tL7c1XBMtWHHqVpS5ChmiAAoe4PF/d5+ULzV9sLAzs= +github.com/golangci/revgrep v0.5.3/go.mod h1:U4R/s9dlXZsg8uJmaR1GrloUr14D7qDl8gi2iPXJH8k= +github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed h1:IURFTjxeTfNFP0hTEi1YKjB/ub8zkpaOqFFMApi2EAs= +github.com/golangci/unconvert v0.0.0-20240309020433-c5143eacb3ed/go.mod h1:XLXN8bNw4CGRPaqgl3bv/lhz7bsGPh4/xSaMTbo2vkQ= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1 h1:gK4Kx5IaGY9CD5sPJ36FHiBJ6ZXl0kilRiiCj+jdYp4= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6 h1:k7nVchz72niMH6YLQNvHSdIE7iqsQxK1P41mySCvssg= +github.com/google/pprof v0.0.0-20240424215950-a892ee059fd6/go.mod h1:kf6iHlnVGwgKolg33glAes7Yg/8iWP8ukqeldJSO7jw= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= +github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= +github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gordonklaus/ineffassign v0.1.0 h1:y2Gd/9I7MdY1oEIt+n+rowjBNDcLQq3RsH5hwJd0f9s= +github.com/gordonklaus/ineffassign v0.1.0/go.mod h1:Qcp2HIAYhR7mNUVSIxZww3Guk4it82ghYcEXIAk+QT0= +github.com/goss-org/GOnetstat v0.0.0-20230101144325-22be0bd9e64d h1:50mlZKtg8BUvBtFs0ioVpSgMMwcKaJefg/2pZ+lQf98= +github.com/goss-org/GOnetstat v0.0.0-20230101144325-22be0bd9e64d/go.mod h1:MBdRlloGIbpQVDuH5Gxg3hjqwZBCZsmFqbYPaeR6r0M= +github.com/goss-org/go-ps v0.0.0-20230609005227-7b318e6a56e5 h1:NW0Jo4leMIrQxNOyOkBu4yBnygI37m0Ey0EUUgvzr+8= +github.com/goss-org/go-ps v0.0.0-20230609005227-7b318e6a56e5/go.mod h1:FYj70SLmogHdTTDGnIVaaK0iczROlsxmoMCwfAUuIE8= +github.com/goss-org/goss v0.4.9 h1:Lh5QDDbGXST0gyOmgVlw5xC8EXYKCNZhFzmz24sgEdg= +github.com/goss-org/goss v0.4.9/go.mod h1:VWVUDZMOIT7s04FwPFfKNhY2ZH2Q5mw06yWPATxh7FI= +github.com/gostaticanalysis/analysisutil v0.7.1 h1:ZMCjoue3DtDWQ5WyU16YbjbQEQ3VuzwxALrpYd+HeKk= +github.com/gostaticanalysis/analysisutil v0.7.1/go.mod h1:v21E3hY37WKMGSnbsw2S/ojApNWb6C1//mXO48CXbVc= +github.com/gostaticanalysis/comment v1.4.1/go.mod h1:ih6ZxzTHLdadaiSnF5WY3dxUoXfXAlTaRzuaNDlSado= +github.com/gostaticanalysis/comment v1.4.2 h1:hlnx5+S2fY9Zo9ePo4AhgYsYHbM2+eAv8m/s1JiCd6Q= +github.com/gostaticanalysis/comment v1.4.2/go.mod h1:KLUTGDv6HOCotCH8h2erHKmpci2ZoR8VPu34YA2uzdM= +github.com/gostaticanalysis/forcetypeassert v0.1.0 h1:6eUflI3DiGusXGK6X7cCcIgVCpZ2CiZ1Q7jl6ZxNV70= +github.com/gostaticanalysis/forcetypeassert v0.1.0/go.mod h1:qZEedyP/sY1lTGV1uJ3VhWZ2mqag3IkWsDHVbplHXak= +github.com/gostaticanalysis/nilerr v0.1.1 h1:ThE+hJP0fEp4zWLkWHWcRyI2Od0p7DlgYG3Uqrmrcpk= +github.com/gostaticanalysis/nilerr v0.1.1/go.mod h1:wZYb6YI5YAxxq0i1+VJbY0s2YONW0HU0GPE3+5PWN4A= +github.com/gostaticanalysis/testutil v0.3.1-0.20210208050101-bfb5c8eec0e4/go.mod h1:D+FIZ+7OahH3ePw/izIEeH5I06eKs1IKI4Xr64/Am3M= +github.com/gostaticanalysis/testutil v0.4.0 h1:nhdCmubdmDF6VEatUNjgUZBJKWRqugoISdUv3PPQgHY= +github.com/gostaticanalysis/testutil v0.4.0/go.mod h1:bLIoPefWXrRi/ssLFWX1dx7Repi5x3CuviD3dgAZaBU= github.com/hashicorp/consul/api v1.25.1 h1:CqrdhYzc8XZuPnhIYZWH45toM0LB9ZeYr/gvpLVI3PE= github.com/hashicorp/consul/api v1.25.1/go.mod h1:iiLVwR/htV7mas/sy0O+XSuEnrdBUUydemjxcUrAt4g= github.com/hashicorp/consul/sdk v0.14.1 h1:ZiwE2bKb+zro68sWzZ1SgHF3kRMBZ94TwOCFRF4ylPs= @@ -85,8 +284,8 @@ github.com/hashicorp/go-multierror v1.1.0/go.mod h1:spPvp8C1qA32ftKqdAHm4hHTbPw+ github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.7.6 h1:TwRYfx2z2C4cLbXmT8I5PgP/xmuqASDyiVuGYfs9GZM= -github.com/hashicorp/go-retryablehttp v0.7.6/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= github.com/hashicorp/go-rootcerts v1.0.2/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-safetemp v1.0.0 h1:2HR189eFNrjHQyENnQMMpCiBAsRxzbTMIgBhEyExpmo= @@ -104,30 +303,48 @@ github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/b github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= -github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= -github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.7.0 h1:5tqGy27NaOTB8yJKUZELlFAS/LTKJkrmONwQKeRZfjY= +github.com/hashicorp/go-version v1.7.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= -github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= github.com/hashicorp/hcl/v2 v2.22.0 h1:hkZ3nCtqeJsDhPRFz5EA9iwcG1hNWGePOTw6oyul12M= github.com/hashicorp/hcl/v2 v2.22.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA= +github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= github.com/hashicorp/mdns v1.0.4/go.mod h1:mtBihi+LeNXGtG8L9dX59gAEa12BDtBQSp4v/YAJqrc= github.com/hashicorp/memberlist v0.5.0 h1:EtYPN8DpAURiapus508I4n9CzHs2W+8NZGbmmR/prTM= github.com/hashicorp/memberlist v0.5.0/go.mod h1:yvyXLpo0QaGE59Y7hDTsTzDD25JYBZ4mHgHUZ8lrOI0= -github.com/hashicorp/packer-plugin-sdk v0.5.2 h1:N+9qzkZLkjR0bgY+l5wFvrTN0G/Mf9f7g2yLsrDjmFI= -github.com/hashicorp/packer-plugin-sdk v0.5.2/go.mod h1:0LRUBS6CPClHvq6zPoGRi7C+cZDAIEaW4CeH4LhWWuc= +github.com/hashicorp/packer-plugin-sdk v0.5.4 h1:5Bl5DMEa//G4gBNcl842JopM9L4KSSsxpvB4W1lEwIA= +github.com/hashicorp/packer-plugin-sdk v0.5.4/go.mod h1:ALm0ZIK3c/F4iOqPNi7xVuHTgrR5dxzOK+DhFN5DHj4= github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY= github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hashicorp/vault/api v1.14.0 h1:Ah3CFLixD5jmjusOgm8grfN9M0d+Y8fVR2SW0K6pJLU= github.com/hashicorp/vault/api v1.14.0/go.mod h1:pV9YLxBGSz+cItFDd8Ii4G17waWOQ32zVjMWHe/cOqk= github.com/hashicorp/yamux v0.1.1 h1:yrQxtgseBDrq9Y652vSRDvsKCJKOUD+GzTS4Y0Y8pvE= github.com/hashicorp/yamux v0.1.1/go.mod h1:CtWFDAQgb7dxtzFs4tWbplKIe2jSi3+5vKbgIO0SLnQ= +github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM= +github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg= +github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/huandu/xstrings v1.5.0 h1:2ag3IFq9ZDANvthTwTiqSSZLjDc+BedvHPAp5tJy2TI= +github.com/huandu/xstrings v1.5.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE= +github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= +github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8= +github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw= github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869 h1:IPJ3dvxmJ4uczJe5YQdrYB16oTJlGSC/OyZDqUk9xX4= github.com/jehiah/go-strftime v0.0.0-20171201141054-1d33003b3869/go.mod h1:cJ6Cj7dQo+O6GJNiMx+Pa94qKj+TG8ONdKHgMNIyyag= +github.com/jgautheron/goconst v1.7.1 h1:VpdAG7Ca7yvvJk5n8dMwQhfEZJh95kl/Hl9S1OI5Jkk= +github.com/jgautheron/goconst v1.7.1/go.mod h1:aAosetZ5zaeC/2EfMeRswtxUFBpe2Hr7HzkgX4fanO4= +github.com/jingyugao/rowserrcheck v1.1.1 h1:zibz55j/MJtLsjP1OF4bSdgXxwL1b+Vn7Tjzq7gFzUs= +github.com/jingyugao/rowserrcheck v1.1.1/go.mod h1:4yvlZSDb3IyDTUZJUmpZfm2Hwok+Dtp+nu2qOq+er9c= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af h1:KA9BjwUk7KlCh6S9EAGWBt1oExIUv9WyNCiRz5amv48= +github.com/jirfag/go-printf-func-name v0.0.0-20200119135958-7558a9eaa5af/go.mod h1:HEWGJkRDzjJY2sqdDwxccsGicWEf9BQOZsq2tV+xzM0= +github.com/jjti/go-spancheck v0.6.1 h1:ZK/wE5Kyi1VX3PJpUO2oEgeoI4FWOUm7Shb2Gbv5obI= +github.com/jjti/go-spancheck v0.6.1/go.mod h1:vF1QkOO159prdo6mHRxak2CpzDpHAfKiPUDP/NeRnX8= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= @@ -135,13 +352,53 @@ github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfC github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= +github.com/julz/importas v0.1.0 h1:F78HnrsjY3cR7j0etXy5+TU1Zuy7Xt08X/1aJnH5xXY= +github.com/julz/importas v0.1.0/go.mod h1:oSFU2R4XK/P7kNBrnL/FEQlDGN1/6WoxXEjSSXO0DV0= +github.com/karamaru-alpha/copyloopvar v1.1.0 h1:x7gNyKcC2vRBO1H2Mks5u1VxQtYvFiym7fCjIP8RPos= +github.com/karamaru-alpha/copyloopvar v1.1.0/go.mod h1:u7CIfztblY0jZLOQZgH3oYsJzpC2A7S6u/lfgSXHy0k= +github.com/kisielk/errcheck v1.7.0 h1:+SbscKmWJ5mOK/bO1zS60F5I9WwZDWOfRsC4RwfwRV0= +github.com/kisielk/errcheck v1.7.0/go.mod h1:1kLL+jV4e+CFfueBmI1dSK2ADDyQnlrnrY/FqKluHJQ= +github.com/kkHAIKE/contextcheck v1.1.5 h1:CdnJh63tcDe53vG+RebdpdXJTc9atMgGqdx8LXxiilg= +github.com/kkHAIKE/contextcheck v1.1.5/go.mod h1:O930cpht4xb1YQpK+1+AgoM3mFsvxr7uyFptcnWTYUA= github.com/klauspost/compress v1.15.9 h1:wKRjX6JRtDdrE9qwa4b/Cip7ACOshUI4smpCQanqjSY= github.com/klauspost/compress v1.15.9/go.mod h1:PhcZ0MbTNciWF3rruxRgKxI5NkcHHrHUDtV4Yw2GlzU= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kulti/thelper v0.6.3 h1:ElhKf+AlItIu+xGnI990no4cE2+XaSu1ULymV2Yulxs= +github.com/kulti/thelper v0.6.3/go.mod h1:DsqKShOvP40epevkFrvIwkCMNYxMeTNjdWL4dqWHZ6I= +github.com/kunwardeep/paralleltest v1.0.10 h1:wrodoaKYzS2mdNVnc4/w31YaXFtsc21PCTdvWJ/lDDs= +github.com/kunwardeep/paralleltest v1.0.10/go.mod h1:2C7s65hONVqY7Q5Efj5aLzRCNLjw2h4eMc9EcypGjcY= +github.com/kyoh86/exportloopref v0.1.11 h1:1Z0bcmTypkL3Q4k+IDHMWTcnCliEZcaPiIe0/ymEyhQ= +github.com/kyoh86/exportloopref v0.1.11/go.mod h1:qkV4UF1zGl6EkF1ox8L5t9SwyeBAZ3qLMd6up458uqA= +github.com/lasiar/canonicalheader v1.1.1 h1:wC+dY9ZfiqiPwAexUApFush/csSPXeIi4QqyxXmng8I= +github.com/lasiar/canonicalheader v1.1.1/go.mod h1:cXkb3Dlk6XXy+8MVQnF23CYKWlyA7kfQhSw2CcZtZb0= +github.com/ldez/gomoddirectives v0.2.4 h1:j3YjBIjEBbqZ0NKtBNzr8rtMHTOrLPeiwTkfUJZ3alg= +github.com/ldez/gomoddirectives v0.2.4/go.mod h1:oWu9i62VcQDYp9EQ0ONTfqLNh+mDLWWDO+SO0qSQw5g= +github.com/ldez/tagliatelle v0.5.0 h1:epgfuYt9v0CG3fms0pEgIMNPuFf/LpPIfjk4kyqSioo= +github.com/ldez/tagliatelle v0.5.0/go.mod h1:rj1HmWiL1MiKQuOONhd09iySTEkUuE/8+5jtPYz9xa4= +github.com/leonklingele/grouper v1.1.2 h1:o1ARBDLOmmasUaNDesWqWCIFH3u7hoFlM84YrjT3mIY= +github.com/leonklingele/grouper v1.1.2/go.mod h1:6D0M/HVkhs2yRKRFZUoGjeDy7EZTfFBE9gl4kjmIGkA= +github.com/lufeee/execinquery v1.2.1 h1:hf0Ems4SHcUGBxpGN7Jz78z1ppVkP/837ZlETPCEtOM= +github.com/lufeee/execinquery v1.2.1/go.mod h1:EC7DrEKView09ocscGHC+apXMIaorh4xqSxS/dy8SbM= +github.com/macabu/inamedparam v0.1.3 h1:2tk/phHkMlEL/1GNe/Yf6kkR/hkcUdAEY3L0hjYV1Mk= +github.com/macabu/inamedparam v0.1.3/go.mod h1:93FLICAIk/quk7eaPPQvbzihUdn/QkGDwIZEoLtpH6I= +github.com/magiconair/properties v1.8.6 h1:5ibWZ6iY0NctNGWo87LalDlEZ6R41TqbbDamhfG/Qzo= +github.com/magiconair/properties v1.8.6/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= +github.com/maratori/testableexamples v1.0.0 h1:dU5alXRrD8WKSjOUnmJZuzdxWOEQ57+7s93SLMxb2vI= +github.com/maratori/testableexamples v1.0.0/go.mod h1:4rhjL1n20TUTT4vdh3RDqSizKLyXp7K2u6HgraZCGzE= +github.com/maratori/testpackage v1.1.1 h1:S58XVV5AD7HADMmD0fNnziNHqKvSdDuEKdPD1rNTU04= +github.com/maratori/testpackage v1.1.1/go.mod h1:s4gRK/ym6AMrqpOa/kEbQTV4Q4jb7WeLZzVhVVVOQMc= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26 h1:gWg6ZQ4JhDfJPqlo2srm/LN17lpybq15AryXIRcWYLE= +github.com/matoous/godox v0.0.0-20230222163458-006bad1f9d26/go.mod h1:1BELzlh859Sh1c6+90blK8lbYy0kwQf1bYlBhBysy1s= +github.com/matryer/is v1.4.0 h1:sosSmIWwkYITGrxZ25ULNDeKiMNzFSr4V/eqBQP0PeE= +github.com/matryer/is v1.4.0/go.mod h1:8I/i5uYgLzgsgEloJE1U6xx5HkBQpAZvepWuujKwMRU= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= github.com/mattn/go-colorable v0.1.6/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -155,14 +412,26 @@ github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOA github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.17/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.9 h1:Lm995f3rfxdpd6TSmuVCHVb/QhupuXlYr8sCI/QdE+0= +github.com/mattn/go-runewidth v0.0.9/go.mod h1:H031xJmbD/WCDINGzjvQ9THkh0rPKHF+m2gUSrubnMI= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= +github.com/mgechev/revive v1.3.7 h1:502QY0vQGe9KtYJ9FpxMz9rL+Fc/P13CI5POL4uHCcE= +github.com/mgechev/revive v1.3.7/go.mod h1:RJ16jUbF0OWC3co/+XTxmFNgEpUPwnnA0BRllX2aDNA= github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKjuso= -github.com/miekg/dns v1.1.41 h1:WMszZWJG0XmzbK9FEmzH2TVcqYzFesusSIB41b8KHxY= github.com/miekg/dns v1.1.41/go.mod h1:p6aan82bvRIyn+zDIv9xYNUpwa73JcSh9BKwknJysuI= +github.com/miekg/dns v1.1.61 h1:nLxbwF3XxhwVSm8g9Dghm9MHPaUZuqhPiGL+675ZmEs= +github.com/miekg/dns v1.1.61/go.mod h1:mnAarhS3nWaW+NVP2wTkYVIZyHNJ098SJZUki3eykwQ= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/cli v1.1.0/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI= +github.com/mitchellh/cli v1.1.5 h1:OxRIeJXpAMztws/XHlN2vu6imG5Dpq+j61AzAX5fLng= +github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= +github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= +github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= +github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= @@ -176,18 +445,56 @@ github.com/mitchellh/mapstructure v0.0.0-20160808181253-ca63d7c062ee/go.mod h1:F github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/reflectwalk v1.0.0 h1:9D+8oIskB4VJBN5SFlmc27fSlIBZaov1Wpk/IfikLNY= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= +github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= +github.com/moby/sys/mountinfo v0.7.1 h1:/tTvQaSJRr2FshkhXiIpux6fQ2Zvc4j7tAhMTStAG2g= +github.com/moby/sys/mountinfo v0.7.1/go.mod h1:IJb6JQeOklcdMU9F5xQ8ZALD+CUr5VlGpwtX+VE0rpI= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moricho/tparallel v0.3.1 h1:fQKD4U1wRMAYNngDonW5XupoB/ZGJHdpzrWqgyg9krA= +github.com/moricho/tparallel v0.3.1/go.mod h1:leENX2cUv7Sv2qDgdi0D0fCftN8fRC67Bcn8pqzeYNI= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/nakabonne/nestif v0.3.1 h1:wm28nZjhQY5HyYPx+weN3Q65k6ilSBxDb8v5S81B81U= +github.com/nakabonne/nestif v0.3.1/go.mod h1:9EtoZochLn5iUprVDmDjqGKPofoUEBL8U4Ngq6aY7OE= +github.com/nishanths/exhaustive v0.12.0 h1:vIY9sALmw6T/yxiASewa4TQcFsVYZQQRUQJhKRf3Swg= +github.com/nishanths/exhaustive v0.12.0/go.mod h1:mEZ95wPIZW+x8kC4TgC+9YCUgiST7ecevsVDTgc2obs= +github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm/w98Vk= +github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= +github.com/nunnatsa/ginkgolinter v0.16.2 h1:8iLqHIZvN4fTLDC0Ke9tbSZVcyVHoBs0HIbnVSxfHJk= +github.com/nunnatsa/ginkgolinter v0.16.2/go.mod h1:4tWRinDN1FeJgU+iJANW/kz7xKN5nYRAOfJDQUS9dOQ= github.com/nywilken/go-cty v1.13.3 h1:03U99oXf3j3g9xgqAE3YGpixCjM8Mg09KZ0Ji9LzX0o= github.com/nywilken/go-cty v1.13.3/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= +github.com/oleiade/reflections v1.0.1 h1:D1XO3LVEYroYskEsoSiGItp9RUxG6jWnCVvrqH0HHQM= +github.com/oleiade/reflections v1.0.1/go.mod h1:rdFxbxq4QXVZWj0F+e9jqjDkc7dbp97vkRixKo2JR60= +github.com/olekukonko/tablewriter v0.0.5 h1:P2Ga83D34wi1o9J6Wh1mRuqd4mF/x/lgBS7N7AbDhec= +github.com/olekukonko/tablewriter v0.0.5/go.mod h1:hPp6KlRPjbx+hW8ykQs1w3UBbZlj6HuIJcUGPhkA7kY= +github.com/onsi/ginkgo/v2 v2.17.3 h1:oJcvKpIb7/8uLpDDtnQuf18xVnwKp8DTD7DQ6gTd/MU= +github.com/onsi/ginkgo/v2 v2.17.3/go.mod h1:nP2DPOQoNsQmsVyv5rDA8JkXQoCs6goXIvr/PRJ1eCc= +github.com/onsi/gomega v1.33.1 h1:dsYjIxxSR755MDmKVsaFQTE22ChNBcuuTWgkUDSubOk= +github.com/onsi/gomega v1.33.1/go.mod h1:U4R44UsT+9eLIaYRB2a5qajjtQYn0hauxvRm16AVYg0= +github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= +github.com/otiai10/copy v1.14.0 h1:dCI/t1iTdYGtkvCuBG2BgR6KZa83PTclw4U5n2wAllU= +github.com/otiai10/copy v1.14.0/go.mod h1:ECfuL02W+/FkTWZWgQqXPWZgW9oeKCSQ5qVfSc4qc4w= +github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= +github.com/otiai10/curr v1.0.0/go.mod h1:LskTG5wDwr8Rs+nNQ+1LlxRjAtTZZjtJW4rMXl6j4vs= +github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT91xUo= +github.com/otiai10/mint v1.3.1/go.mod h1:/yxELlJQ0ufhjUwhshSj+wFjZ78CnZ48/1wtmBH1OTc= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY= github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc= +github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ= +github.com/pelletier/go-toml v1.9.5 h1:4yBQzkHv+7BHq2PQUZF3Mx0IYxG7LsP222s7Agd3ve8= +github.com/pelletier/go-toml v1.9.5/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= +github.com/pelletier/go-toml/v2 v2.2.2 h1:aYUidT7k73Pcl9nb2gScu7NSrKCSHIDE89b3+6Wq+LM= +github.com/pelletier/go-toml/v2 v2.2.2/go.mod h1:1t835xjRzz80PqgE6HHgN2JOsmgYu/h4qDAS4n929Rs= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= +github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= @@ -195,77 +502,277 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/polyfloyd/go-errorlint v1.5.2 h1:SJhVik3Umsjh7mte1vE0fVZ5T1gznasQG3PV7U5xFdA= +github.com/polyfloyd/go-errorlint v1.5.2/go.mod h1:sH1QC1pxxi0fFecsVIzBmxtrgd9IF/SkJpA6wqyKAJs= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= +github.com/prashantv/gostub v1.1.0 h1:BTyx3RfQjRHnUWaGF9oQos79AlQ5k8WNktv7VGvVH4g= +github.com/prashantv/gostub v1.1.0/go.mod h1:A5zLQHz7ieHGG7is6LLXLz7I8+3LZzsrV0P1IAHhP5U= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU= +github.com/prometheus/client_golang v1.19.1 h1:wZWJDwK+NameRJuPGDhlnFgx8e8HN3XHQeLaYJFJBOE= +github.com/prometheus/client_golang v1.19.1/go.mod h1:mP78NwGzrVks5S2H6ab8+ZZGJLZUq1hoULYBAYBw1Ho= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4= +github.com/prometheus/common v0.55.0 h1:KEi6DK7lXW/m7Ig5i47x0vRzuBsHuvJdi5ee6Y3G1dc= +github.com/prometheus/common v0.55.0/go.mod h1:2SECS4xJG1kd8XF9IcM1gMX6510RAEL65zxzNImwdc8= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= +github.com/quasilyte/go-ruleguard v0.4.2 h1:htXcXDK6/rO12kiTHKfHuqR4kr3Y4M0J0rOL6CH/BYs= +github.com/quasilyte/go-ruleguard v0.4.2/go.mod h1:GJLgqsLeo4qgavUoL8JeGFNS7qcisx3awV/w9eWTmNI= +github.com/quasilyte/go-ruleguard/dsl v0.3.22 h1:wd8zkOhSNr+I+8Qeciml08ivDt1pSXe60+5DqOpCjPE= +github.com/quasilyte/go-ruleguard/dsl v0.3.22/go.mod h1:KeCP03KrjuSO0H1kTuZQCWlQPulDV6YMIXmpQss17rU= +github.com/quasilyte/gogrep v0.5.0 h1:eTKODPXbI8ffJMN+W2aE0+oL0z/nh8/5eNdiO34SOAo= +github.com/quasilyte/gogrep v0.5.0/go.mod h1:Cm9lpz9NZjEoL1tgZ2OgeUKPIxL1meE7eo60Z6Sk+Ng= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727 h1:TCg2WBOl980XxGFEZSS6KlBGIV0diGdySzxATTWoqaU= +github.com/quasilyte/regex/syntax v0.0.0-20210819130434-b3f0c404a727/go.mod h1:rlzQ04UMyJXu/aOvhd8qT+hvDrFpiwqp8MRXDY9szc0= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567 h1:M8mH9eK4OUR4lu7Gd+PU1fV2/qnDNfzT635KRSObncs= +github.com/quasilyte/stdinfo v0.0.0-20220114132959-f7386bf02567/go.mod h1:DWNGW8A4Y+GyBgPuaQJuWiy0XYftx4Xm/y5Jqk9I6VQ= +github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= +github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= +github.com/ryancurrah/gomodguard v1.3.2 h1:CuG27ulzEB1Gu5Dk5gP8PFxSOZ3ptSdP5iI/3IXxM18= +github.com/ryancurrah/gomodguard v1.3.2/go.mod h1:LqdemiFomEjcxOqirbQCb3JFvSxH2JUYMerTFd3sF2o= +github.com/ryanrolds/sqlclosecheck v0.5.1 h1:dibWW826u0P8jNLsLN+En7+RqWWTYrjCB9fJfSfdyCU= +github.com/ryanrolds/sqlclosecheck v0.5.1/go.mod h1:2g3dUjoS6AL4huFdv6wn55WpLIDjY7ZgUR4J8HOO/XQ= github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= +github.com/samber/lo v1.46.0 h1:w8G+oaCPgz1PoCJztqymCFaKwXt+5cCXn51uPxExFfQ= +github.com/samber/lo v1.46.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= +github.com/sanposhiho/wastedassign/v2 v2.0.7 h1:J+6nrY4VW+gC9xFzUc+XjPD3g3wF3je/NsJFwFK7Uxc= +github.com/sanposhiho/wastedassign/v2 v2.0.7/go.mod h1:KyZ0MWTwxxBmfwn33zh3k1dmsbF2ud9pAAGfoLfjhtI= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= +github.com/sashamelentyev/interfacebloat v1.1.0 h1:xdRdJp0irL086OyW1H/RTZTr1h/tMEOsumirXcOJqAw= +github.com/sashamelentyev/interfacebloat v1.1.0/go.mod h1:+Y9yU5YdTkrNvoX0xHc84dxiN1iBi9+G8zZIhPVoNjQ= +github.com/sashamelentyev/usestdlibvars v1.26.0 h1:LONR2hNVKxRmzIrZR0PhSF3mhCAzvnr+DcUiHgREfXE= +github.com/sashamelentyev/usestdlibvars v1.26.0/go.mod h1:9nl0jgOfHKWNFS43Ojw0i7aRoS4j6EBye3YBhmAIRF8= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc= +github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9 h1:rnO6Zp1YMQwv8AyxzuwsVohljJgp4L0ZqiCgtACsPsc= +github.com/securego/gosec/v2 v2.20.1-0.20240525090044-5f0084eb01a9/go.mod h1:dg7lPlu/xK/Ut9SedURCoZbVCR4yC7fM65DtH9/CDHs= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c h1:W65qqJCIOVP4jpqPQ0YvHYKwcMEMVWIzWC5iNQQfBTU= +github.com/shazow/go-diff v0.0.0-20160112020656-b6b7b6733b8c/go.mod h1:/PevMnwAxekIXwN8qQyfc5gl2NlkB3CQlkizAbOkeBs= +github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= +github.com/shopspring/decimal v1.4.0 h1:bxl37RwXBklmTi0C79JfXCEBD1cqqHt0bbgBAGFp81k= +github.com/shopspring/decimal v1.4.0/go.mod h1:gawqmDU56v4yIKSwfBSFip1HdCCXN8/+DMd9qYNcwME= +github.com/shurcooL/go v0.0.0-20180423040247-9e1955d9fb6e/go.mod h1:TDJrrUr11Vxrven61rcy3hJMUqaf/CLWYhHNPmT14Lk= +github.com/shurcooL/go-goon v0.0.0-20170922171312-37c2f522c041/go.mod h1:N5mDOmsrJOB+vfqUK+7DmDyjhSLIIBnXo9lvZJj3MWQ= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ= +github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= +github.com/sivchari/containedctx v1.0.3 h1:x+etemjbsh2fB5ewm5FeLNi5bUjK0V8n0RB+Wwfd0XE= +github.com/sivchari/containedctx v1.0.3/go.mod h1:c1RDvCbnJLtH4lLcYD/GqwiBSSf4F5Qk0xld2rBqzJ4= +github.com/sivchari/tenv v1.7.1 h1:PSpuD4bu6fSmtWMxSGWcvqUUgIn7k3yOJhOIzVWn8Ak= +github.com/sivchari/tenv v1.7.1/go.mod h1:64yStXKSOxDfX47NlhVwND4dHwfZDdbp2Lyl018Icvg= +github.com/sonatard/noctx v0.0.2 h1:L7Dz4De2zDQhW8S0t+KUjY0MAQJd6SgVwhzNIc4ok00= +github.com/sonatard/noctx v0.0.2/go.mod h1:kzFz+CzWSjQ2OzIm46uJZoXuBpa2+0y3T36U18dWqIo= +github.com/sourcegraph/go-diff v0.7.0 h1:9uLlrd5T46OXs5qpp8L/MTltk0zikUGi0sNNyCpA8G0= +github.com/sourcegraph/go-diff v0.7.0/go.mod h1:iBszgVvyxdc8SFZ7gm69go2KDdt3ag071iBaWPF6cjs= +github.com/spf13/afero v1.11.0 h1:WJQKhtpdm3v2IzqG8VMqrr6Rf3UYpEF239Jy9wNepM8= +github.com/spf13/afero v1.11.0/go.mod h1:GH9Y3pIexgf1MTIWtNGyogA5MwRIDXGUr+hbWNoBjkY= +github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.7.0 h1:ntdiHjuueXFgm5nzDRdOS4yfT43P5Fnud6DH50rz/7w= +github.com/spf13/cast v1.7.0/go.mod h1:ancEpBxwJDODSW/UG4rDrAqiKolqNNh2DX3mk86cAdo= +github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= +github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= +github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= +github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= +github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.12.0 h1:CZ7eSOd3kZoaYDLbXnmzgQI5RlciuXBMA+18HwHRfZQ= +github.com/spf13/viper v1.12.0/go.mod h1:b6COn30jlNxbm/V2IqWiNWkJ+vZNiMNksliPCiuKtSI= +github.com/ssgreg/nlreturn/v2 v2.2.1 h1:X4XDI7jstt3ySqGU86YGAURbxw3oTDPK9sPEi6YEwQ0= +github.com/ssgreg/nlreturn/v2 v2.2.1/go.mod h1:E/iiPB78hV7Szg2YfRgyIrk1AD6JVMTRkkxBiELzh2I= +github.com/stbenjam/no-sprintf-host-port v0.1.1 h1:tYugd/yrm1O0dV+ThCbaKZh195Dfm07ysF0U6JQXczc= +github.com/stbenjam/no-sprintf-host-port v0.1.1/go.mod h1:TLhvtIvONRzdmkFiio4O8LHsN9N74I+PhRquPsxpL0I= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/objx v0.5.2 h1:xuMeJ0Sdp5ZMRXx/aWO6RZxdr3beISkG5/G/aIRr3pY= +github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/8L+MA= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= +github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= +github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +github.com/subosito/gotenv v1.4.1 h1:jyEFiXpy21Wm81FBN71l9VoMMV8H8jG+qIK3GCpY6Qs= +github.com/subosito/gotenv v1.4.1/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c h1:+aPplBwWcHBo6q9xrfWdMrT9o4kltkmmvpemgIjep/8= +github.com/t-yuki/gocover-cobertura v0.0.0-20180217150009-aaee18c8195c/go.mod h1:SbErYREK7xXdsRiigaQiQkI9McGRzYMvlKYaP3Nimdk= +github.com/tdakkota/asciicheck v0.2.0 h1:o8jvnUANo0qXtnslk2d3nMKTFNlOnJjRrNcj0j9qkHM= +github.com/tdakkota/asciicheck v0.2.0/go.mod h1:Qb7Y9EgjCLJGup51gDHFzbI08/gbGhL/UVhYIPWG2rg= +github.com/tenntenn/modver v1.0.1 h1:2klLppGhDgzJrScMpkj9Ujy3rXPUspSjAcev9tSEBgA= +github.com/tenntenn/modver v1.0.1/go.mod h1:bePIyQPb7UeioSRkw3Q0XeMhYZSMx9B8ePqg6SAMGH0= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3 h1:f+jULpRQGxTSkNYKJ51yaw6ChIqO+Je8UqsTKN/cDag= +github.com/tenntenn/text/transform v0.0.0-20200319021203-7eef512accb3/go.mod h1:ON8b8w4BN/kE1EOhwT0o+d62W65a6aPw1nouo9LMgyY= +github.com/tetafro/godot v1.4.16 h1:4ChfhveiNLk4NveAZ9Pu2AN8QZ2nkUGFuadM9lrr5D0= +github.com/tetafro/godot v1.4.16/go.mod h1:2oVxTBSftRTh4+MVfUaUXR6bn2GDXCaMcOG4Dk3rfio= +github.com/tidwall/gjson v1.17.1 h1:wlYEnwqAHgzmhNUFfw7Xalt2JzQvsMx2Se4PcoFCT/U= +github.com/tidwall/gjson v1.17.1/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= +github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= +github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= +github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= +github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966 h1:quvGphlmUVU+nhpFa4gg4yJyTRJ13reZMDHrKwYw53M= +github.com/timakin/bodyclose v0.0.0-20230421092635-574207250966/go.mod h1:27bSVNWSBOHm+qRp1T9qzaIpsWEP6TbUnei/43HK+PQ= +github.com/timonwong/loggercheck v0.9.4 h1:HKKhqrjcVj8sxL7K77beXh0adEm6DLjV/QOGeMXEVi4= +github.com/timonwong/loggercheck v0.9.4/go.mod h1:caz4zlPcgvpEkXgVnAJGowHAMW2NwHaNlpS8xDbVhTg= +github.com/tomarrell/wrapcheck/v2 v2.8.3 h1:5ov+Cbhlgi7s/a42BprYoxsr73CbdMUTzE3bRDFASUs= +github.com/tomarrell/wrapcheck/v2 v2.8.3/go.mod h1:g9vNIyhb5/9TQgumxQyOEqDHsmGYcGsVMOx/xGkqdMo= +github.com/tommy-muehle/go-mnd/v2 v2.5.1 h1:NowYhSdyE/1zwK9QCLeRb6USWdoif80Ie+v+yU8u1Zw= +github.com/tommy-muehle/go-mnd/v2 v2.5.1/go.mod h1:WsUAkMJMYww6l/ufffCD3m+P7LEvr8TnZn9lwVDlgzw= github.com/tv42/httpunix v0.0.0-20150427012821-b75d8614f926/go.mod h1:9ESjWnEqriFuLhtthL60Sar/7RFoluCcXsuvEwTV5KM= github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn0= github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/ulikunitz/xz v0.5.10 h1:t92gobL9l3HE202wg3rlk19F6X+JOxl9BBrCCMYEYd8= github.com/ulikunitz/xz v0.5.10/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14= +github.com/ultraware/funlen v0.1.0 h1:BuqclbkY6pO+cvxoq7OsktIXZpgBSkYTQtmwhAK81vI= +github.com/ultraware/funlen v0.1.0/go.mod h1:XJqmOQja6DpxarLj6Jj1U7JuoS8PvL4nEqDaQhy22p4= +github.com/ultraware/whitespace v0.1.1 h1:bTPOGejYFulW3PkcrqkeQwOd6NKOOXvmGD9bo/Gk8VQ= +github.com/ultraware/whitespace v0.1.1/go.mod h1:XcP1RLD81eV4BW8UhQlpaR+SDc2givTvyI8a586WjW8= +github.com/uudashr/gocognit v1.1.2 h1:l6BAEKJqQH2UpKAPKdMfZf5kE4W/2xk8pfU1OVLvniI= +github.com/uudashr/gocognit v1.1.2/go.mod h1:aAVdLURqcanke8h3vg35BC++eseDm66Z7KmchI5et4k= +github.com/xen0n/gosmopolitan v1.2.2 h1:/p2KTnMzwRexIW8GlKawsTWOxn7UHA+jCMF/V8HHtvU= +github.com/xen0n/gosmopolitan v1.2.2/go.mod h1:7XX7Mj61uLYrj0qmeN0zi7XDon9JRAEhYQqAPLVNTeg= +github.com/yagipy/maintidx v1.0.0 h1:h5NvIsCz+nRDapQ0exNv4aJ0yXSI0420omVANTv3GJM= +github.com/yagipy/maintidx v1.0.0/go.mod h1:0qNf/I/CCZXSMhsRsrEPDZ+DkekpKLXAJfsTACwgXLk= +github.com/yeya24/promlinter v0.3.0 h1:JVDbMp08lVCP7Y6NP3qHroGAO6z2yGKQtS5JsjqtoFs= +github.com/yeya24/promlinter v0.3.0/go.mod h1:cDfJQQYv9uYciW60QT0eeHlFodotkYZlL+YcPQN+mW4= +github.com/ykadowak/zerologlint v0.1.5 h1:Gy/fMz1dFQN9JZTPjv1hxEk+sRWm05row04Yoolgdiw= +github.com/ykadowak/zerologlint v0.1.5/go.mod h1:KaUskqF3e/v59oPmdq1U1DnKcuHokl2/K1U4pmIELKg= +github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= +gitlab.com/bosi/decorder v0.4.2 h1:qbQaV3zgwnBZ4zPMhGLW4KZe7A7NwxEhJx39R3shffo= +gitlab.com/bosi/decorder v0.4.2/go.mod h1:muuhHoaJkA9QLcYHq4Mj8FJUwDZ+EirSHRiaTcTf6T8= +go-simpler.org/assert v0.9.0 h1:PfpmcSvL7yAnWyChSjOz6Sp6m9j5lyK8Ok9pEL31YkQ= +go-simpler.org/assert v0.9.0/go.mod h1:74Eqh5eI6vCK6Y5l3PI8ZYFXG4Sa+tkr70OIPJAUr28= +go-simpler.org/musttag v0.12.2 h1:J7lRc2ysXOq7eM8rwaTYnNrHd5JwjppzB6mScysB2Cs= +go-simpler.org/musttag v0.12.2/go.mod h1:uN1DVIasMTQKk6XSik7yrJoEysGtR2GRqvWnI9S7TYM= +go-simpler.org/sloglint v0.7.1 h1:qlGLiqHbN5islOxjeLXoPtUdZXb669RW+BDQ+xOSNoU= +go-simpler.org/sloglint v0.7.1/go.mod h1:OlaVDRh/FKKd4X4sIMbsz8st97vomydceL146Fthh/c= +go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= +go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= +go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= +go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= +go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI= +go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= +go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= +go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60= +go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg= golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3H3cr1v9wB50oz8l4C4h62xy7jSTY= -golang.org/x/crypto v0.23.0 h1:dIJU/v2J8Mdglj/8rJ6UUOM3Zc9zLZxVZwwxMooUSAI= -golang.org/x/crypto v0.23.0/go.mod h1:CKFgDieR+mRhux2Lsu27y0fO304Db0wZe70UKqHu0v8= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29 h1:ooxPy7fPvB4kwsA2h+iBNHkAbp/4JxTSwCmvdjEYmug= -golang.org/x/exp v0.0.0-20230321023759-10a507213a29/go.mod h1:CxIveKay+FTh1D0yPZemJVgC/95VzuuOLq5Qi4xnoYc= -golang.org/x/mod v0.13.0 h1:I/DsJXRlw/8l/0c24sM9yb0T4z9liZTduXvdAWYiysY= -golang.org/x/mod v0.13.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= +golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio= +golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= +golang.org/x/crypto v0.19.0/go.mod h1:Iy9bg/ha4yyC70EfRS8jz+B6ybOBKMaSxLj6P6oBDfU= +golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs= +golang.org/x/crypto v0.26.0 h1:RrRspgV4mU+YwB4FYnuBoKsUapNIL5cohGAmSH3azsw= +golang.org/x/crypto v0.26.0/go.mod h1:GY7jblb9wI+FOo5y8/S2oY4zWP07AkOJ4+jxCqdqn54= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 h1:LfspQV/FYTatPTr/3HzIcmiUFH7PGP+OQ6mgDYo3yuQ= +golang.org/x/exp v0.0.0-20240222234643-814bf88cf225/go.mod h1:CxmFvTBINI24O/j8iY7H1xHzx2i4OsyguNBmN/uPtqc= +golang.org/x/exp/typeparams v0.0.0-20220428152302-39d4317da171/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20230203172020-98cc5a0785f9/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f h1:phY1HzDcf18Aq9A8KkmRtY9WvOFIxN8wgfvy6Zm1DV8= +golang.org/x/exp/typeparams v0.0.0-20240314144324-c7f7c6466f7f/go.mod h1:AbB0pIl9nAr9wVwH+Z2ZpaocVmF5I4GyWCDIsVjR0bk= +golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.1/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= +golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.9.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.15.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.16.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.19.0 h1:fEdghXQSo20giMthA7cd28ZC+jts4amQ3YMXiP5oMQ8= +golang.org/x/mod v0.19.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190613194153-d28f0bde5980/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20190923162816-aa69164e4478/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= +golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= +golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.25.0 h1:d/OCCoBEUq33pjydKrGQhw7IlUPI2Oylr+8qLx49kac= -golang.org/x/net v0.25.0/go.mod h1:JkAGAh7GEvH74S6FOH42FLoXpXbE/aqXSrIQjXgsiwM= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= +golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= +golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= +golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA= +golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44= +golang.org/x/net v0.22.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.27.0 h1:5K3Njcw06/l2y9vpGCSdcxWOYHOUk3dVNGDXN+FvAys= +golang.org/x/net v0.27.0/go.mod h1:dDi0PyhWNoiUOrAS8uXv/vnScO4wnHQO4mj9fn/RytE= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ= -golang.org/x/sync v0.4.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190922100055-0a153f010e69/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -273,46 +780,131 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210303074136-134d130e1a04/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211105183446-c75c47738b0c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220702020025-31831981b65f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.20.0 h1:Od9JTbYCk261bKm4M/mw7AklTlFYIa0bIp9BgSm1S8Y= -golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.23.0 h1:YfKFowiIMvtgl1UERQoTPPToxltDeZfbj4H7dVUCwmM= +golang.org/x/sys v0.23.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/telemetry v0.0.0-20240228155512-f48c80bd79b2/go.mod h1:TeRTkGYfJXctD9OcfyVLyj2J3IxLnKwHJR8f4D8a3YE= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= +golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo= +golang.org/x/term v0.10.0/go.mod h1:lpqdcUyK/oCiQxvxVrppt5ggO2KCZ5QblwqPnfZ6d5o= +golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU= +golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk= +golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58= +golang.org/x/term v0.23.0 h1:F6D4vR+EHoL9/sWAWgAR1H2DcHr4PareCbAaCo1RpuU= +golang.org/x/term v0.23.0/go.mod h1:DgV24QBUrK6jhZXl+20l6UWznPlwAHm1Q1mGHtydmSk= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.15.0 h1:h1V/4gjBv8v9cjcR6+AR5+/cIYK5N/WAgiv4xlsEtAk= -golang.org/x/text v0.15.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= -golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4= -golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc= +golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= +golang.org/x/time v0.5.0 h1:o7cqy6amK/52YcAKIPlM3a+Fpj35zvRj2TP+e1xFSfk= +golang.org/x/time v0.5.0/go.mod h1:3BpzKBy/shNhVucY/MWOyx10tF3SFh9QdLuxbVysPQM= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190321232350-e250d351ecad/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190907020128-2ca718005c18/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.14.0 h1:jvNa2pY0M4r62jkRQ6RwEZZyPcymeL9XZMLBbV7U2nc= -golang.org/x/tools v0.14.0/go.mod h1:uYBEerGOWcJyEORxN+Ek8+TT266gXkNlHdJBwexUsBg= +golang.org/x/tools v0.0.0-20190910044552-dd2b5c81c578/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191108193012-7d206e10da11/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200324003944-a576cf524670/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= +golang.org/x/tools v0.0.0-20200724022722-7017fd6b1305/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20200820010801-b793a1359eac/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= +golang.org/x/tools v0.0.0-20201023174141-c8cfbd0f21e6/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= +golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1-0.20210205202024-ef80cdb6ec6d/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1-0.20210302220138-2ac05c832e1a/go.mod h1:9bzcO0MWcOuT0tm1iBGzDVPshzfwoVvREIui8C+MHqU= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.9/go.mod h1:nABZi5QlRsZVlzPpHl034qft6wpY4eDcsTt5AaioBiU= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.11/go.mod h1:SgwaegtQh8clINPpECJMqnxLv9I09HLqnW3RMqW0CA4= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= +golang.org/x/tools v0.3.0/go.mod h1:/rWhSS2+zyEVwoJf8YAX6L2f0ntZ7Kn/mGgAWcipA5k= +golang.org/x/tools v0.5.0/go.mod h1:N+Kgy78s5I24c24dU8OfWNEotWjutIs8SnJvn5IDq+k= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/tools v0.11.0/go.mod h1:anzJrxPjNtfgiYQYirP2CPGzGLxrH2u2QBhn6Bf3qY8= +golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.19.0/go.mod h1:qoJWxmGSIBmAeriMx19ogtrEPrGtDbPK634QFIcLAhc= +golang.org/x/tools v0.23.0 h1:SGsXPZ+2l4JsgaCKkx+FQ9YZ5XEtA1GZYuoDjenLjvg= +golang.org/x/tools v0.23.0/go.mod h1:pnu6ufv6vQkll6szChhK3C3L/ruaIv5eBeztNG8wtsI= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +google.golang.org/protobuf v1.34.2 h1:6xV6lTsCfpGD21XK49h7MhtcApnLqkfYgPcdHftf6hg= +google.golang.org/protobuf v1.34.2/go.mod h1:qYOHts0dSfpeUzUFpOMr/WGzszTmLH+DiWniOlNbLDw= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= +gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA= +gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU= gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= +gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gotest.tools/gotestsum v1.12.0 h1:CmwtaGDkHxrZm4Ib0Vob89MTfpc3GrEFMJKovliPwGk= +gotest.tools/gotestsum v1.12.0/go.mod h1:fAvqkSptospfSbQw26CTYzNwnsE/ztqLeyhP0h67ARY= +gotest.tools/v3 v3.5.1 h1:EENdUnS3pdur5nybKYIh2Vfgc8IUNBjxDPSjtiJcOzU= +gotest.tools/v3 v3.5.1/go.mod h1:isy3WKz7GK6uNw/sbHzfKBLvlvXwUyV06n6brMxxopU= +honnef.co/go/tools v0.4.7 h1:9MDAWxMoSnB6QoSqiVr7P5mtkT9pOc1kSxchzPCnqJs= +honnef.co/go/tools v0.4.7/go.mod h1:+rnGS1THNh8zMwnd2oVOTL9QF6vmfyG6ZXBULae2uc0= +mvdan.cc/gofumpt v0.6.0 h1:G3QvahNDmpD+Aek/bNOLrFR2XC6ZAdo62dZu65gmwGo= +mvdan.cc/gofumpt v0.6.0/go.mod h1:4L0wf+kgIPZtcCWXynNS2e6bhmj73umwnuXSZarixzA= +mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f h1:lMpcwN6GxNbWtbpI1+xzFLSW8XzX0u72NttUGVFjO3U= +mvdan.cc/unparam v0.0.0-20240528143540-8a5130ca722f/go.mod h1:RSLa7mKKCNeTTMHBw5Hsy2rfJmd6O2ivt9Dw9ZqCQpQ= diff --git a/main.go b/main.go index f7bd4d2..7efa7d4 100644 --- a/main.go +++ b/main.go @@ -4,15 +4,12 @@ import ( "fmt" "os" + "github.com/YaleUniversity/packer-provisioner-goss/provisioner/goss" "github.com/hashicorp/packer-plugin-sdk/plugin" "github.com/hashicorp/packer-plugin-sdk/version" - - "github.com/YaleUniversity/packer-provisioner-goss/provisioner/goss" ) -var ( - Version = "0.0.1" -) +var Version = "0.0.1" func main() { pps := plugin.NewSet() @@ -20,7 +17,6 @@ func main() { pps.SetVersion(version.InitializePluginVersion(Version, "")) err := pps.Run() - if err != nil { fmt.Fprintln(os.Stderr, err.Error()) os.Exit(1) diff --git a/provisioner/goss/goss.go b/provisioner/goss/goss.go new file mode 100644 index 0000000..6b4a0f2 --- /dev/null +++ b/provisioner/goss/goss.go @@ -0,0 +1,107 @@ +package goss + +import ( + "context" + "fmt" + "os" + + gs "github.com/goss-org/goss" + "github.com/hashicorp/packer-plugin-sdk/packer" + "gopkg.in/yaml.v2" +) + +// Block is an interface that all blocks must implement. +type Block interface { + // Name returns the name of the block. + Name() string + + // Validate validates the block attributes and sets sane defaults. + Validate() error + + // Run executes the blocks command. + Run(ctx context.Context, ui packer.Ui, comm packer.Communicator) error + + // String returns a string representation of the command. + String() string +} + +func ValidateBlocks(blocks ...Block) error { + var errs *packer.MultiError + + for _, b := range blocks { + if err := b.Validate(); err != nil { + errs = packer.MultiErrorAppend(errs, fmt.Errorf("error in %s block: %w", b.Name(), err)) + } + } + + if errs != nil && len(errs.Errors) > 0 { + return errs + } + + return nil +} + +func RunBlocks(ctx context.Context, ui packer.Ui, comm packer.Communicator, blocks ...Block) error { + for _, b := range blocks { + ui.Say(fmt.Sprintf("Start execution of \"%s\" ...", b.Name())) + + ui.Message(fmt.Sprintf("executing \"%s\"", SanitizeCommands(b.String()))) + + if err := b.Run(ctx, ui, comm); err != nil { + return fmt.Errorf("error running \"%s\": %w", b.Name(), err) + } + + ui.Say(fmt.Sprintf("Successfully finished \"%s\"", b.Name())) + } + + return nil +} + +// GetIncludedGossFiles returns a list of included goss files (if any) +// which then needs to be uploaded to the target system. +func GetIncludedGossFiles(gossFile string, varsFile string, varsInline map[string]string, envVars map[string]string) ([]string, error) { + var cfg gs.GossConfig + var currentTemplateFilter gs.TemplateFilter + + // actually set any env vars, its ok to set these as env vars are inherited down to child processes + // but we do not spawn any child processes so this wont have any affects on the system + for k, v := range envVars { + os.Setenv(k, v) + } + + varsInlineStr := "" + for k, v := range varsInline { + varsInlineStr += fmt.Sprintf("%s: %s\n", k, v) + } + + currentTemplateFilter, err := gs.NewTemplateFilter(varsFile, varsInlineStr) + if err != nil { + return nil, err + } + + b, err := os.ReadFile(gossFile) + if err != nil { + return nil, err + } + + data, err := currentTemplateFilter(b) + if err != nil { + return nil, err + } + + if yaml.Unmarshal(data, &cfg) != nil { + return nil, fmt.Errorf("cannot parse gossfile: %w", err) + } + + if len(cfg.Gossfiles) > 0 { + files := []string{} + + for k := range cfg.Gossfiles { + files = append(files, k) + } + + return files, nil + } + + return []string{}, nil +} diff --git a/provisioner/goss/goss_installation.go b/provisioner/goss/goss_installation.go new file mode 100644 index 0000000..8a7565e --- /dev/null +++ b/provisioner/goss/goss_installation.go @@ -0,0 +1,226 @@ +//go:generate packer-sdc struct-markdown + +package goss + +import ( + "context" + "fmt" + "path/filepath" + "slices" + "strings" + + "github.com/hashicorp/packer-plugin-sdk/packer" +) + +// Installation holds all installation params. +type Installation struct { + // execute goss validate with sudo permissions + UseSudo bool `mapstructure:"use_sudo"` + + /// Goss Version to download + Version string `mapstructure:"version"` + + // Architecture of the target system + Arch string `mapstructure:"arch"` + + // OS of the target system. + OS string `mapstructure:"os"` + + // URL to download the goss binary from. + URL string `mapstructure:"url"` + + // If true SSL checks are skipped. + SkipSSL bool `mapstructure:"skip_ssl"` + + // Path to download the goss binary to. + DownloadPath string `mapstructure:"download_path"` + + // Username for basic auth. + Username string `mapstructure:"username"` + + // Password for basic auth. + Password string `mapstructure:"password"` + + // EnvVars any env vars. + EnvVars map[string]string `mapstructure:"env_vars"` + + // If true installation of the goss binary is skipped. + SkipInstallation bool `mapstructure:"skip_installation"` +} + +func (i *Installation) Name() string { + return "curl/wget installation" +} + +func (i *Installation) Validate() error { + // no sudo on windows + //nolint: staticcheck + if i.UseSudo && strings.Title(i.OS) == Windows { + return fmt.Errorf("sudo is not supported on windows") + } + + // if no version specified, use latest + if i.Version == "" { + i.Version = "latest" + } else { + // remove any leading v as that is already in the DownloadURL + i.Version = strings.TrimPrefix(i.Version, "v") + } + + // if no arch specified, assume linux_x86 + if i.Arch == "" { + i.Arch = DefaultArch + } + + // if no OS specified, assume linux_x86 + //nolint: staticcheck + if i.OS == "" { + i.OS = DefaultOS + } else if !slices.Contains(validOS, strings.Title(i.OS)) { + return fmt.Errorf("invalid OS. Valid options: %v", validOS) + } + + if i.URL == "" { + if i.Version == Latest { + i.URL = fmt.Sprintf(LatestVersionDownloadURL, i.OS, i.Arch) + } else { + i.URL = fmt.Sprintf(VersionDownloadURL, i.Version, i.OS, i.Arch) + } + } + + if i.DownloadPath == "" { + i.DownloadPath = fmt.Sprintf(DefaultDownloadPath, i.Version, i.OS, i.Arch) + } + + return nil +} + +func (i *Installation) Run(ctx context.Context, ui packer.Ui, comm packer.Communicator) error { + if i.SkipInstallation { + ui.Message(fmt.Sprintf("Skipping %s", i.Name())) + + return nil + } + + // create download paths + ui.Message(fmt.Sprintf("Creating download path \"%s\" ...", filepath.Dir(i.DownloadPath))) + mkDirsCmd := &packer.RemoteCmd{Command: fmt.Sprintf(mkDirCmd, filepath.Dir(i.DownloadPath))} + + err := mkDirsCmd.RunWithUi(ctx, comm, ui) + if err != nil || mkDirsCmd.ExitStatus() != 0 { + return fmt.Errorf("error creating directories: \"%s\"", filepath.Dir(i.DownloadPath)) + } + + // download + ui.Message(fmt.Sprintf("Installing goss version %s from %s", i.Version, i.URL)) + downloadCmd := &packer.RemoteCmd{Command: i.String()} + + err = downloadCmd.RunWithUi(ctx, comm, ui) + if err != nil || downloadCmd.ExitStatus() != 0 { + return fmt.Errorf("unable to download goss: %w", err) + } + + // make executable, and test invocation + ui.Message("Trying to invoke goss ...") + installCmd := &packer.RemoteCmd{Command: fmt.Sprintf(InstallCmd, i.DownloadPath, i.DownloadPath)} + + err = installCmd.RunWithUi(ctx, comm, ui) + if err != nil || installCmd.ExitStatus() != 0 { + return fmt.Errorf("unable to install goss: %w", err) + } + + return nil +} + +// nolint: cyclop +func (i *Installation) String() string { + return SanitizeCommands(fmt.Sprintf( + DownloadCmd, + // curl + + // env vars + ExportEnvVars(i.EnvVars, i.OS), + + // sudo + func() string { + if i.UseSudo { + return "sudo" + } + + return "" + }(), + + // ssl flag curl + func() string { + if i.SkipSSL { + return "-k" + } + + return "" + }(), + + // basic auth curl + func() string { + basicAuth := "" + + if i.Username != "" { + basicAuth += fmt.Sprintf("-u=\"%s\"", i.Username) + } + + if i.Password != "" { + basicAuth += fmt.Sprintf(":\"%s\"", i.Password) + } + + return basicAuth + }(), + + // output path curl + i.DownloadPath, + + // download url + i.URL, + + // wget + // env vars + ExportEnvVars(i.EnvVars, i.OS), + + // sudo + func() string { + if i.UseSudo { + return "sudo" + } + + return "" + }(), + + // ssl flag wget + func() string { + if i.SkipSSL { + return "--no-check-certificate" + } + + return "" + }(), + + // basic auth wget + func() string { + basicAuth := "" + + if i.Username != "" { + basicAuth += fmt.Sprintf("--user=\"%s\" ", i.Username) + } + + if i.Password != "" { + basicAuth += fmt.Sprintf("--password=\"%s\" ", i.Password) + } + + return basicAuth + }(), + + // output path curl + i.DownloadPath, + + // download url + i.URL, + )) +} diff --git a/provisioner/goss/goss_render.go b/provisioner/goss/goss_render.go new file mode 100644 index 0000000..a2aacdd --- /dev/null +++ b/provisioner/goss/goss_render.go @@ -0,0 +1,217 @@ +// //go:generate packer-sdc struct-markdown + +package goss + +// import ( +// "context" +// "fmt" +// "os" +// "path" +// "path/filepath" +// "slices" + +// "github.com/hashicorp/packer-plugin-sdk/packer" +// ) + +// // Render holds all goss render params. +// type Render struct { +// remotePath string +// gossBinaryPath string + +// // execute goss render with sudo permissions +// UseSudo bool `mapstructure:"use_sudo"` + +// // if true enabling goss render debug mode. +// Debug bool `mapstructure:"debug"` + +// // Path to the goss file +// GossFile string `mapstructure:"goss_file"` + +// // Path to the vars file +// VarsFile string `mapstructure:"vars_file"` + +// // map of vars to render the goss file with. +// VarsInline map[string]string `mapstructure:"vars_inline"` + +// // EnvVars any env vars. +// EnvVars map[string]string `mapstructure:"env_vars"` + +// // Path to write the goss output to. +// OutputFile string `mapstructure:"output_file"` + +// // If true goss rendering is skipped. +// SkipRender bool `mapstructure:"skip"` +// } + +// func (r *Render) Name() string { +// return "goss render" +// } + +// func (r *Render) Validate() error { +// if r.gossBinaryPath == "" { +// r.gossBinaryPath = fmt.Sprintf(DefaultDownloadPath, Latest, DefaultOS, DefaultArch) +// } + +// if r.OutputFile == "" { +// r.OutputFile = DefaultGossSpecFile +// } + +// if r.GossFile == "" { +// r.GossFile = DefaultGossFile +// } + +// if r.remotePath == "" { +// r.remotePath = DefaultRemotePath +// } + +// return nil +// } + +// // nolint: cyclop +// func (r *Render) Run(ctx context.Context, ui packer.Ui, comm packer.Communicator) error { +// if r.SkipRender { +// ui.Message(fmt.Sprintf("Skipping %s", r.Name())) + +// return nil +// } + +// files := []string{r.GossFile} + +// if r.VarsFile != "" { +// files = append(files, r.VarsFile) +// } + +// ui.Message(fmt.Sprintf("uploading %v to target system ....", files)) + +// for _, src := range files { +// s, err := os.Stat(src) +// if err != nil { +// return fmt.Errorf("error stating file: %w", err) +// } + +// if !s.Mode().IsRegular() { +// return fmt.Errorf("file is not regular: %s", src) +// } + +// f, err := os.Open(src) +// if err != nil { +// return fmt.Errorf("error opening file: %w", err) +// } + +// defer f.Close() + +// dst := path.Join(r.remotePath, filepath.Base(src)) + +// ui.Message(fmt.Sprintf("Uploading \"%s\" to \"%s\"", src, dst)) + +// if err := comm.Upload(dst, f, nil); err != nil { +// return fmt.Errorf("error uploading file \"%s\" to \"%s\": %w", src, dst, err) +// } +// } + +// ui.Message(fmt.Sprintf("Running \"%s\"", r)) + +// renderCmd := &packer.RemoteCmd{Command: r.String()} + +// if err := renderCmd.RunWithUi(ctx, comm, ui); err != nil { +// return err +// } + +// if r.Debug { +// ui.Message("rendered goss spec:") + +// outputCmd := &packer.RemoteCmd{Command: fmt.Sprintf("cat %s", path.Join(r.remotePath, r.OutputFile))} + +// if err := outputCmd.RunWithUi(ctx, comm, ui); err != nil { +// return err +// } +// } + +// return nil +// } + +// func (r *Render) String() string { +// return SanitizeCommands(fmt.Sprintf( +// RenderCmd, + +// // remote path +// r.remotePath, + +// // env vars +// func() string { +// if len(r.EnvVars) == 0 { +// return "" +// } + +// envs := "" + +// keys := MapKeys(r.EnvVars) +// slices.Sort(keys) + +// for _, k := range keys { +// envs += fmt.Sprintf("%s=%s ", k, r.EnvVars[k]) +// } + +// return "export " + envs + ";" +// }(), + +// // sudo +// func() string { +// if r.UseSudo { +// return "sudo" +// } + +// return "" +// }(), + +// // goss binary path +// r.gossBinaryPath, + +// // goss file +// func() string { +// if r.GossFile != "" { +// return fmt.Sprintf("--gossfile=\"%s\"", r.GossFile) +// } + +// return "" +// }(), + +// // goss vars +// func() string { +// if r.VarsFile != "" { +// return fmt.Sprintf("--vars=\"%s\"", r.VarsFile) +// } + +// return "" +// }(), + +// // vars inline +// func() string { +// if len(r.VarsFile) == 0 { +// return "" +// } + +// vars := "" +// keys := MapKeys(r.VarsInline) +// slices.Sort(keys) + +// for _, k := range keys { +// vars += fmt.Sprintf("--vars-inline='%s: %s' ", k, r.VarsInline[k]) +// } + +// return vars +// }(), + +// // debug +// func() string { +// if r.Debug { +// return "-d" +// } + +// return "" +// }(), + +// // spec file +// path.Join(r.remotePath, r.OutputFile), +// )) +// } diff --git a/provisioner/goss/goss_test.go b/provisioner/goss/goss_test.go new file mode 100644 index 0000000..7e47a78 --- /dev/null +++ b/provisioner/goss/goss_test.go @@ -0,0 +1,156 @@ +package goss + +import ( + "testing" + + "github.com/stretchr/testify/require" +) + +// nolint: lll +func TestBlocks(t *testing.T) { + testCases := []struct { + name string + b Block + exp string + err bool + }{ + { + // TODO: avoid hardcoding the version for latest + name: "default installation", + b: &Installation{}, + exp: "curl -sL -o /tmp/goss-latest-Linux-amd64 https://github.com/goss-org/goss/releases/latest/download/goss-Linux-amd64 || wget -q -O /tmp/goss-latest-Linux-amd64 https://github.com/goss-org/goss/releases/latest/download/goss-Linux-amd64", + }, + { + name: "various parameters", + b: &Installation{ + Version: "0.4.2", + SkipSSL: true, + UseSudo: true, + Arch: "amd64", + OS: "Linux", + DownloadPath: "/tmp", + Username: "user", + Password: "pass", + EnvVars: map[string]string{ + "FOO": "bar", + }, + }, + exp: "export FOO=bar ; sudo curl -sL -k -u=\"user\":\"pass\" -o /tmp https://github.com/goss-org/goss/releases/download/v0.4.2/goss-Linux-amd64 || export FOO=bar ; sudo wget -q --no-check-certificate --user=\"user\" --password=\"pass\" -O /tmp https://github.com/goss-org/goss/releases/download/v0.4.2/goss-Linux-amd64", + }, + { + name: "forbidden installation", + b: &Installation{ + UseSudo: true, + OS: "Windows", + }, + err: true, + }, + // { + // name: "default render", + // b: &Render{}, + // exp: "cd /tmp && /tmp/goss-latest-Linux-amd64 --gossfile=\"./goss.yaml\" render > /tmp/goss-spec.yaml", + // }, + // { + // name: "various parameter render", + // b: &Render{ + // UseSudo: true, + // Debug: true, + // GossFile: "./goss_file.yaml", + // VarsFile: "./vars_file.yaml", + // VarsInline: map[string]string{ + // "Foo": "Bar", + // "Foo2": "Bar", + // }, + // EnvVars: map[string]string{ + // "FOO": "bar", + // }, + // OutputFile: "goss-spec.yaml", + // }, + // exp: "cd /tmp && export FOO=bar ; sudo /tmp/goss-latest-Linux-amd64 --gossfile=\"./goss_file.yaml\" --vars=\"./vars_file.yaml\" --vars-inline='Foo: Bar' --vars-inline='Foo2: Bar' render -d > /tmp/goss-spec.yaml", + // }, + { + name: "default validate", + b: &Validate{}, + exp: "/tmp/goss-latest-Linux-amd64 --gossfile=\"/tmp/goss.yaml\" validate --retry-timeout=0s --sleep=1s", + }, + { + name: "various parameter validate", + b: &Validate{ + UseSudo: true, + GossFile: "./goss_file.yaml", + VarsFile: "./vars_file.yaml", + VarsInline: map[string]string{ + "Foo": "Bar", + "Foo2": "Bar", + }, + EnvVars: map[string]string{ + "FOO": "bar", + }, + targetOS: Linux, + RetryTimeout: "4s", + Format: "junit", + FormatOptions: "perfdata", + Loglevel: "TRACE", + Package: "rpm", + OutputFile: "output.xml", + }, + exp: "sudo export FOO=bar ; /tmp/goss-latest-Linux-amd64 --package=\"rpm\" --log-level=\"TRACE\" --gossfile=\"/tmp/goss_file.yaml\" --vars=\"/tmp/vars_file.yaml\" --vars-inline='Foo: Bar' --vars-inline='Foo2: Bar' validate --retry-timeout=4s --sleep=1s --format=\"junit\" --format-options=\"perfdata\" | tee \"/tmp/output.xml\"", + }, + } + + for _, tc := range testCases { + err := ValidateBlocks(tc.b) + + if tc.err { + require.Error(t, err, tc.name) + + continue + } else { + require.NoError(t, err, tc.name) + } + + require.Equal(t, tc.exp, tc.b.String(), tc.name) + } +} + +func TestGetIncludedGossFiles(t *testing.T) { + testCases := []struct { + name string + gossFile string + varsFile string + varsInline map[string]string + envVars map[string]string + exp []string + err bool + }{ + { + name: "test", + gossFile: "./testdata/gossfile_included.yaml", + varsFile: "./testdata/vars.yaml", + varsInline: map[string]string{ + "installed": "true", + }, + envVars: map[string]string{ + "installed": "true", + }, + exp: []string{"./testdata/goss.yaml"}, + }, + { + name: "no files", + gossFile: "./testdata/goss.yaml", + exp: []string{}, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + files, err := GetIncludedGossFiles(tc.gossFile, tc.varsFile, tc.varsInline, tc.envVars) + if tc.err { + require.Error(t, err, tc.name) + } else { + require.NoError(t, err) + require.Equal(t, tc.exp, files, tc.name) + } + }) + } +} diff --git a/provisioner/goss/goss_validate.go b/provisioner/goss/goss_validate.go new file mode 100644 index 0000000..a94eb67 --- /dev/null +++ b/provisioner/goss/goss_validate.go @@ -0,0 +1,297 @@ +//go:generate packer-sdc struct-markdown + +package goss + +import ( + "context" + "fmt" + "os" + "path" + "path/filepath" + "slices" + + "github.com/hashicorp/packer-plugin-sdk/packer" +) + +// Validate holds all goss validate params. +type Validate struct { + gossBinaryPath string + targetOS string + + // execute goss validate with sudo permissions + UseSudo bool `mapstructure:"use_sudo"` + + // Path to the goss file + GossFile string `mapstructure:"goss_file"` + + // Path to the vars file + VarsFile string `mapstructure:"vars_file"` + + // map of vars to render the goss file with. + VarsInline map[string]string `mapstructure:"vars_inline"` + + // Package type to use + Package string `mapstructure:"package"` + + // Loglevel to use + Loglevel string `mapstructure:"log_level"` + + // retry timeout. + RetryTimeout string `mapstructure:"retry_timeout"` + + // time to sleep between retries + Sleep string `mapstructure:"sleep"` + + // Goss Output Format. + Format string `mapstructure:"format"` + + // Path to write the goss output to. + OutputFile string `mapstructure:"output_file"` + + // Format options for the output. + FormatOptions string `mapstructure:"format_options"` + + // EnvVars any env vars. + EnvVars map[string]string `mapstructure:"env_vars"` +} + +func (v *Validate) Name() string { + return "goss validate" +} + +// nolint: cyclop +func (v *Validate) Validate() error { + if v.gossBinaryPath == "" { + v.gossBinaryPath = fmt.Sprintf(DefaultDownloadPath, Latest, DefaultOS, DefaultArch) + } + + if v.Sleep == "" { + v.Sleep = DefaultSleep + } + + if v.RetryTimeout == "" { + v.RetryTimeout = DefaultRetryTimeout + } + + if v.GossFile == "" { + v.GossFile = DefaultGossFile + } + + if v.Loglevel != "" && !slices.Contains(validLogLevel, v.Loglevel) { + return fmt.Errorf("invalid log level. Valid options: %v", validLogLevel) + } + + if v.Package != "" && !slices.Contains(ValidPackageTypes, v.Package) { + return fmt.Errorf("invalid package type. Valid options: %v", ValidPackageTypes) + } + + if v.Format != "" && !slices.Contains(ValidFormats, v.Format) { + return fmt.Errorf("invalid format. Valid options: %v", ValidFormats) + } + + if v.FormatOptions != "" && !slices.Contains(ValidFormatOptions, v.FormatOptions) { + return fmt.Errorf("invalid format option. Valid options: %v", ValidFormatOptions) + } + + return nil +} + +// nolint: cyclop +func (v *Validate) Run(ctx context.Context, ui packer.Ui, comm packer.Communicator) error { + files := []string{v.GossFile} + + ui.Message(fmt.Sprintf("Detecting wether \"%s\" includes other gossfiles ...", v.GossFile)) + + gossfiles, err := GetIncludedGossFiles(v.GossFile, v.VarsFile, v.VarsInline, v.EnvVars) + if err != nil { + ui.Message(fmt.Sprintf("Error detecting included goss files: %s. Continuing as not fatal", err.Error())) + } else { + ui.Message(fmt.Sprintf("Found %v referenced in \"%s\"", gossfiles, v.GossFile)) + + files = append(files, gossfiles...) + if v.VarsFile != "" { + files = append(files, v.VarsFile) + } + } + + ui.Message(fmt.Sprintf("Uploading %v to target system ....", files)) + + for _, src := range files { + s, err := os.Stat(src) + if err != nil { + return fmt.Errorf("error stating file: %w", err) + } + + if !s.Mode().IsRegular() { + return fmt.Errorf("file is not regular: %s", src) + } + + f, err := os.Open(src) + if err != nil { + return fmt.Errorf("error opening file: %w", err) + } + + defer f.Close() + + dst := path.Join(DefaultRemotePath, src) + + // create dirs + mkDirsCmd := &packer.RemoteCmd{Command: fmt.Sprintf(mkDirCmd, path.Join(DefaultRemotePath, filepath.Dir(src)))} + + err = mkDirsCmd.RunWithUi(ctx, comm, ui) + if err != nil || mkDirsCmd.ExitStatus() != 0 { + return fmt.Errorf("error creating directories: %s", path.Join(DefaultRemotePath, filepath.Dir(src))) + } + + ui.Message(fmt.Sprintf("Uploading \"%s\" to \"%s\"", src, dst)) + + if err := comm.Upload(dst, f, nil); err != nil { + return fmt.Errorf("error uploading file \"%s\" to \"%s\": %w", src, dst, err) + } + } + + ui.Message("Running goss validate ...") + validateCmd := &packer.RemoteCmd{Command: v.String()} + + // test successful -> exit code 0 + // tests fail -> exit code 1 + // gossfile unparsable -> exit code 78 + err = validateCmd.RunWithUi(ctx, comm, ui) + if err != nil || validateCmd.ExitStatus() != 0 && validateCmd.ExitStatus() != 1 { + return err + } + + ui.Message("goss validate finished") + + if v.OutputFile != "" { + ui.Message(fmt.Sprintf("Downloading goss test result file \"%s\" (target system) to \"%s\" (local) ...", path.Join(DefaultRemotePath, v.OutputFile), filepath.Base(v.OutputFile))) + + if err := DownloadFile(comm, path.Join(DefaultRemotePath, v.OutputFile), filepath.Base(v.OutputFile)); err != nil { + return fmt.Errorf("error downloading \"%s\": %w", path.Join(DefaultRemotePath, v.OutputFile), err) + } + + resultsPath := filepath.Base(v.OutputFile) + if abs, err := filepath.Abs(v.OutputFile); err == nil { + resultsPath = abs + } + + // output the absolute path so its easier for folks to upload the file to their CI/CD system as a test artifact ... + ui.Message(fmt.Sprintf("Successfully downloaded test result file from target system to \"%s\"", resultsPath)) + } + + return nil +} + +// nolint: cyclop +func (v *Validate) String() string { + return SanitizeCommands(fmt.Sprintf( + ValidateCmd, + + // sudo + func() string { + if v.UseSudo { + return "sudo" + } + + return "" + }(), + + // env vars + ExportEnvVars(v.EnvVars, v.targetOS), + + // goss binary path + v.gossBinaryPath, + + // package + func() string { + if v.Package != "" { + return fmt.Sprintf("--package=\"%s\"", v.Package) + } + + return "" + }(), + + // loglevel + func() string { + if v.Package != "" { + return fmt.Sprintf("--log-level=\"%s\"", v.Loglevel) + } + + return "" + }(), + // goss file + func() string { + if v.GossFile != "" { + return fmt.Sprintf("--gossfile=\"%s\"", path.Join(DefaultRemotePath, v.GossFile)) + } + + return "" + }(), + + // goss vars + func() string { + if v.VarsFile != "" { + return fmt.Sprintf("--vars=\"%s\"", path.Join(DefaultRemotePath, v.VarsFile)) + } + + return "" + }(), + + // inline vars + func() string { + if len(v.VarsFile) == 0 { + return "" + } + + vars := "" + + keys := MapKeys(v.VarsInline) + slices.Sort(keys) + + for _, k := range keys { + vars += fmt.Sprintf("--vars-inline='%s: %s' ", k, v.VarsInline[k]) + } + + return vars + }(), + + // retry timeout + v.RetryTimeout, + + // sleep + v.Sleep, + + // format + func() string { + if v.Format != "" { + return fmt.Sprintf("--format=\"%s\"", v.Format) + } + + return "" + }(), + + // format options + func() string { + if v.FormatOptions != "" { + return fmt.Sprintf("--format-options=\"%s\"", v.FormatOptions) + } + + return "" + }(), + + // output file + func() string { + if v.OutputFile != "" { + if v.targetOS == Linux { + return fmt.Sprintf("| tee \"%s\"", path.Join(DefaultRemotePath, v.OutputFile)) + } + + if v.targetOS == Windows { + return fmt.Sprintf("| Tee-Object -FilePath \"%s\"", path.Join(DefaultRemotePath, v.OutputFile)) + } + } + + return "" + }(), + )) +} diff --git a/provisioner/goss/packer-provisioner-goss.go b/provisioner/goss/packer-provisioner-goss.go deleted file mode 100644 index e9a6bc9..0000000 --- a/provisioner/goss/packer-provisioner-goss.go +++ /dev/null @@ -1,581 +0,0 @@ -//go:generate packer-sdc mapstructure-to-hcl2 -type GossConfig - -package goss - -import ( - "context" - "encoding/json" - "errors" - "fmt" - "os" - "path/filepath" - "strings" - - "github.com/hashicorp/hcl/v2/hcldec" - - "github.com/hashicorp/packer-plugin-sdk/packer" - "github.com/hashicorp/packer-plugin-sdk/template/config" - "github.com/hashicorp/packer-plugin-sdk/template/interpolate" -) - -const ( - gossSpecFile = "/tmp/goss-spec.yaml" - gossDebugSpecFile = "/tmp/debug-goss-spec.yaml" - linux = "Linux" - windows = "Windows" -) - -// GossConfig holds the config data coming in from the packer template -type GossConfig struct { - // Goss installation - Version string - Arch string - URL string - DownloadPath string `mapstructure:"download_path"` - Username string - Password string - SkipInstall bool `mapstructure:"skip_install"` - Inspect bool - TargetOs string `mapstructure:"target_os"` - - // An array of tests to run. - Tests []string - - // Goss options for retry and timeouts - RetryTimeout string `mapstructure:"retry_timeout"` - Sleep string `mapstructure:"sleep"` - - // Use Sudo - UseSudo bool `mapstructure:"use_sudo"` - - // skip ssl check flag - SkipSSLChk bool `mapstructure:"skip_ssl"` - - // The --gossfile flag - GossFile string `mapstructure:"goss_file"` - - // The --vars flag - // Optional file containing variables, used within GOSS templating. - // Must be one of the files contained in the Tests array. - // Can be YAML or JSON. - VarsFile string `mapstructure:"vars_file"` - - // The --vars-inline flag - // Optional inline variables that overrides JSON file vars - VarsInline map[string]string `mapstructure:"vars_inline"` - - // Optional env variables - VarsEnv map[string]string `mapstructure:"vars_env"` - - // The remote folder where the goss tests will be uploaded to. - // This should be set to a pre-existing directory, it defaults to /tmp - RemoteFolder string `mapstructure:"remote_folder"` - - // The remote path where the goss tests will be uploaded. - // This defaults to remote_folder/goss - RemotePath string `mapstructure:"remote_path"` - - // Should be download of spec file and debug info be skipped - SkipDownload bool `mapstructure:"skip_download"` - - // The format to use for test output - // Available: [documentation json json_oneline junit nagios nagios_verbose rspecish silent tap] - // Default: rspecish - Format string `mapstructure:"format"` - - // The format options to use for printing test output - // Available: [perfdata verbose pretty] - // Default: verbose - FormatOptions string `mapstructure:"format_options"` - - ctx interpolate.Context -} - -var validFormats = []string{"documentation", "json", "json_oneline", "junit", "nagios", "nagios_verbose", "rspecish", "silent", "tap"} -var validFormatOptions = []string{"perfdata", "verbose", "pretty"} - -// Provisioner implements a packer Provisioner -type Provisioner struct { - config GossConfig -} - -func (p *Provisioner) ConfigSpec() hcldec.ObjectSpec { - return p.config.FlatMapstructure().HCL2Spec() -} - -// Prepare gets the Goss Privisioner ready to run -func (p *Provisioner) Prepare(raws ...interface{}) error { - err := config.Decode(&p.config, &config.DecodeOpts{ - Interpolate: true, - InterpolateContext: &p.config.ctx, - InterpolateFilter: &interpolate.RenderFilter{ - Exclude: []string{}, - }, - }, raws...) - if err != nil { - return err - } - - if p.config.Version == "" { - p.config.Version = "0.4.2" - } - - if p.config.Arch == "" { - p.config.Arch = "amd64" - } - - if p.config.TargetOs == "" { - p.config.TargetOs = linux - } - - if p.config.URL == "" { - p.config.URL = p.getDownloadUrl() - } - - if p.config.DownloadPath == "" { - os := strings.ToLower(p.config.TargetOs) - if p.config.URL == "" { - p.config.DownloadPath = fmt.Sprintf("/tmp/goss-%s-%s-%s", p.config.Version, os, p.config.Arch) - } else { - list := strings.Split(p.config.URL, "/") - - file := strings.Split(list[len(list)-1], "-") - arch := file[2] - if p.isGossAlpha() { - // The format of the alpha files includes an additional entry - // ex: goss-alpha-windows-amd64.exe - arch = file[3] - } - - version := strings.TrimPrefix(list[len(list)-2], "v") - p.config.DownloadPath = fmt.Sprintf("/tmp/goss-%s-%s-%s", version, os, arch) - } - } - - if p.config.RemoteFolder == "" { - p.config.RemoteFolder = "/tmp" - } - - if p.config.RemotePath == "" { - p.config.RemotePath = fmt.Sprintf("%s/goss", p.config.RemoteFolder) - } - - if p.config.Tests == nil { - p.config.Tests = make([]string, 0) - } - - if p.config.GossFile != "" { - p.config.GossFile = fmt.Sprintf("--gossfile %s", p.config.GossFile) - } - - var errs *packer.MultiError - if p.config.Format != "" { - valid := false - for _, candidate := range validFormats { - if p.config.Format == candidate { - valid = true - break - } - } - if !valid { - errs = packer.MultiErrorAppend(errs, - fmt.Errorf("Invalid format choice %s. Valid options: %v", - p.config.Format, validFormats)) - } - } - - if p.config.FormatOptions != "" { - valid := false - for _, candidate := range validFormatOptions { - if p.config.FormatOptions == candidate { - valid = true - break - } - } - if !valid { - errs = packer.MultiErrorAppend(errs, - fmt.Errorf("Invalid format options choice %s. Valid options: %v", - p.config.FormatOptions, validFormatOptions)) - } - } - - if len(p.config.Tests) == 0 { - errs = packer.MultiErrorAppend(errs, - errors.New("tests must be specified")) - } - - for _, path := range p.config.Tests { - if _, err := os.Stat(path); err != nil { - errs = packer.MultiErrorAppend(errs, - fmt.Errorf("Bad test '%s': %s", path, err)) - } - } - - if p.config.TargetOs != linux && p.config.TargetOs != windows { - errs = packer.MultiErrorAppend(errs, - fmt.Errorf("Os must be %s or %s", linux, windows)) - } - - if errs != nil && len(errs.Errors) > 0 { - return errs - } - - return nil -} - -// Provision runs the Goss Provisioner -func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.Communicator, generatedData map[string]interface{}) error { - ui.Say("Provisioning with Goss") - ui.Say(fmt.Sprintf("Configured to run on %s", string(p.config.TargetOs))) - - // For Windows need to create the target directory before download - if err := p.createDir(ui, comm, p.config.RemotePath); err != nil { - return fmt.Errorf("Error creating remote directory: %s", err) - } - - if !p.config.SkipInstall { - if err := p.installGoss(ui, comm); err != nil { - return fmt.Errorf("Error installing Goss: %s", err) - } - } else { - ui.Message("Skipping Goss installation") - } - - ui.Say("Uploading goss tests...") - if p.config.VarsFile != "" { - vf, err := os.Stat(p.config.VarsFile) - if err != nil { - return fmt.Errorf("Error stating file: %s", err) - } - if vf.Mode().IsRegular() { - ui.Message(fmt.Sprintf("Uploading vars file %s", p.config.VarsFile)) - varsDest := filepath.ToSlash(filepath.Join(p.config.RemotePath, filepath.Base(p.config.VarsFile))) - if err := p.uploadFile(ui, comm, varsDest, p.config.VarsFile); err != nil { - return fmt.Errorf("Error uploading vars file: %s", err) - } - } - } - - if len(p.config.VarsInline) != 0 { - ui.Message(fmt.Sprintf("Inline variables are %s", p.inline_vars())) - } - - if len(p.config.VarsEnv) != 0 { - ui.Message(fmt.Sprintf("Env variables are %s", p.envVars())) - } - - for _, src := range p.config.Tests { - s, err := os.Stat(src) - if err != nil { - return fmt.Errorf("Error stating file: %s", err) - } - - if s.Mode().IsRegular() { - ui.Message(fmt.Sprintf("Uploading %s", src)) - dst := filepath.ToSlash(filepath.Join(p.config.RemotePath, filepath.Base(src))) - if err := p.uploadFile(ui, comm, dst, src); err != nil { - return fmt.Errorf("Error uploading goss test: %s", err) - } - } else if s.Mode().IsDir() { - ui.Message(fmt.Sprintf("Uploading Dir %s", src)) - dst := filepath.ToSlash(filepath.Join(p.config.RemotePath, filepath.Base(src))) - if err := p.uploadDir(ui, comm, dst, src); err != nil { - return fmt.Errorf("Error uploading goss test: %s", err) - } - } else { - ui.Message(fmt.Sprintf("Ignoring %s... not a regular file", src)) - } - } - - ui.Say("\n\n\nRunning goss tests...") - if err := p.runGoss(ui, comm); err != nil { - return fmt.Errorf("Error running Goss: %s", err) - } - - if !p.config.SkipDownload { - ui.Say("\n\n\nDownloading spec file and debug info") - if err := p.downloadSpecs(ui, comm); err != nil { - return err - } - } else { - ui.Message("Skipping Goss spec file and debug info download") - } - - return nil -} - -// downloadSpecs downloads the Goss specs from the remote host to current working dir on local machine -func (p *Provisioner) downloadSpecs(ui packer.Ui, comm packer.Communicator) error { - ui.Message(fmt.Sprintf("Downloading Goss specs from, %s and %s to current dir", gossSpecFile, gossDebugSpecFile)) - for _, file := range []string{gossSpecFile, gossDebugSpecFile} { - f, err := os.Create(filepath.Base(file)) - if err != nil { - return fmt.Errorf("Error opening: %s", err) - } - - if err = comm.Download(file, f); err != nil { - _ = f.Close() - return fmt.Errorf("Error downloading %s: %s", file, err) - } - _ = f.Close() - } - return nil -} - -// installGoss downloads the Goss binary on the remote host -func (p *Provisioner) installGoss(ui packer.Ui, comm packer.Communicator) error { - ui.Message(fmt.Sprintf("Installing Goss from, %s", p.config.URL)) - ctx := context.TODO() - - cmd := &packer.RemoteCmd{ - // Fallback on wget if curl failed for any reason (such as not being installed) - Command: fmt.Sprintf( - "curl -sL %s %s -o %s %s || wget -q %s %s -O %s %s", - p.sslFlag("curl"), p.userPass("curl"), p.config.DownloadPath, p.config.URL, - p.sslFlag("wget"), p.userPass("wget"), p.config.DownloadPath, p.config.URL), - } - ui.Message(fmt.Sprintf("Downloading Goss to %s", p.config.DownloadPath)) - if err := cmd.RunWithUi(ctx, comm, ui); err != nil { - return fmt.Errorf("Unable to download Goss: %s", err) - } - cmd = &packer.RemoteCmd{ - Command: fmt.Sprintf("chmod 555 %s && %s --version", p.config.DownloadPath, p.config.DownloadPath), - } - if err := cmd.RunWithUi(ctx, comm, ui); err != nil { - return fmt.Errorf("Unable to install Goss: %s", err) - } - - return nil -} - -// runGoss makes test and render goss commands and passes them to executor func runGossCmd -func (p *Provisioner) runGoss(ui packer.Ui, comm packer.Communicator) error { - goss := fmt.Sprintf("%s", p.config.DownloadPath) - - cmdMap := map[string]string{ - "render": fmt.Sprintf("cd %s && %s %s %s %s %s render > %s", - p.config.RemotePath, p.envVars(), goss, p.config.GossFile, - p.vars(), p.inline_vars(), gossSpecFile, - ), - "render debug": fmt.Sprintf("cd %s && %s %s %s %s %s render -d > %s", - p.config.RemotePath, p.envVars(), goss, p.config.GossFile, - p.vars(), p.inline_vars(), gossDebugSpecFile, - ), - "validate": fmt.Sprintf("cd %s && %s %s %s %s %s %s validate --retry-timeout %s --sleep %s %s %s", - p.config.RemotePath, p.enableSudo(), p.envVars(), goss, p.config.GossFile, - p.vars(), p.inline_vars(), p.retryTimeout(), p.sleep(), p.format(), p.formatOptions(), - ), - } - - for message, cmd := range cmdMap { - ui.Say(fmt.Sprintf("Running GOSS %s command: %s", message, cmd)) - err := p.runGossCmd(ui, comm, &packer.RemoteCmd{Command: cmd}, message) - if err != nil { - return err - } - } - return nil -} - -// runGoss tests and render goss commands. -func (p *Provisioner) runGossCmd(ui packer.Ui, comm packer.Communicator, cmd *packer.RemoteCmd, message string) error { - ctx := context.TODO() - if err := cmd.RunWithUi(ctx, comm, ui); err != nil { - return err - } - if cmd.ExitStatus() != 0 { - // Inspect mode is on. Report failure but don't fail. - if p.config.Inspect { - ui.Say(fmt.Sprintf("Goss %s failed", message)) - ui.Say(fmt.Sprintf("Inspect mode on : proceeding without failing Packer")) - } else { - return fmt.Errorf("goss non-zero exit status") - } - } else { - ui.Say(fmt.Sprintf("Goss %s ran successfully", message)) - } - return nil -} - -func (p *Provisioner) retryTimeout() string { - if p.config.RetryTimeout == "" { - return "0s" // goss default - } - return p.config.RetryTimeout -} - -func (p *Provisioner) sleep() string { - if p.config.Sleep == "" { - return "1s" // goss default - } - return p.config.Sleep -} - -func (p *Provisioner) format() string { - if p.config.Format != "" { - return fmt.Sprintf("-f %s", p.config.Format) - } - return "" -} - -func (p *Provisioner) formatOptions() string { - if p.config.FormatOptions != "" { - return fmt.Sprintf("-o %s", p.config.FormatOptions) - } - return "" -} - -func (p *Provisioner) vars() string { - if p.config.VarsFile != "" { - return fmt.Sprintf("--vars %s", filepath.ToSlash(filepath.Join(p.config.RemotePath, filepath.Base(p.config.VarsFile)))) - } - return "" -} - -func (p *Provisioner) inline_vars() string { - if len(p.config.VarsInline) != 0 { - inlineVarsJson, err := json.Marshal(p.config.VarsInline) - if err == nil { - switch p.config.TargetOs { - case windows: - // don't include single quotes around the json string and replace " with ' otherwise the variables are not recognised - return fmt.Sprintf("--vars-inline %s", strings.Replace(string(inlineVarsJson), "\"", "'", -1)) - default: - return fmt.Sprintf("--vars-inline '%s'", string(inlineVarsJson)) - } - } else { - fmt.Errorf("Error converting inline vars to json string %v", err) - } - } - return "" -} - -func (p *Provisioner) getDownloadUrl() string { - os := strings.ToLower(string(p.config.TargetOs)) - filename := fmt.Sprintf("goss-%s-%s", os, p.config.Arch) - - if p.isGossAlpha() { - filename = fmt.Sprintf("goss-alpha-%s-%s", os, p.config.Arch) - } - - if p.config.TargetOs == windows { - filename = fmt.Sprintf("%s.exe", filename) - } - - return fmt.Sprintf("https://github.com/goss-org/goss/releases/download/v%s/%s", p.config.Version, filename) -} - -func (p *Provisioner) isGossAlpha() bool { - return p.config.VarsEnv["GOSS_USE_ALPHA"] == "1" -} - -func (p *Provisioner) envVars() string { - var sb strings.Builder - for env_var, value := range p.config.VarsEnv { - switch p.config.TargetOs { - case windows: - // Windows requires a call to "set" as separate command seperated by && for each env variable - sb.WriteString(fmt.Sprintf("set \"%s=%s\" && ", env_var, value)) - default: - sb.WriteString(fmt.Sprintf("%s=\"%s\" ", env_var, value)) - } - - } - return sb.String() -} - -func (p *Provisioner) sslFlag(cmdType string) string { - if p.config.SkipSSLChk { - switch cmdType { - case "curl": - return "-k" - case "wget": - return "--no-check-certificate" - default: - return "" - } - } - return "" -} - -// enable sudo if required -func (p *Provisioner) enableSudo() string { - if p.config.UseSudo { - return "sudo" - } - return "" -} - -// Deal with curl & wget username and password -func (p *Provisioner) userPass(cmdType string) string { - if p.config.Username != "" { - switch cmdType { - case "curl": - if p.config.Password == "" { - return fmt.Sprintf("-u %s", p.config.Username) - } - return fmt.Sprintf("-u %s:%s", p.config.Username, p.config.Password) - case "wget": - if p.config.Password == "" { - return fmt.Sprintf("--user=%s", p.config.Username) - } - return fmt.Sprintf("--user=%s --password=%s", p.config.Username, p.config.Password) - default: - return "" - } - } - return "" -} - -// createDir creates a directory on the remote server -func (p *Provisioner) createDir(ui packer.Ui, comm packer.Communicator, dir string) error { - ui.Message(fmt.Sprintf("Creating directory: %s", dir)) - ctx := context.TODO() - - cmd := &packer.RemoteCmd{ - Command: p.mkDir(dir), - } - if err := cmd.RunWithUi(ctx, comm, ui); err != nil { - return err - } - if cmd.ExitStatus() != 0 { - return fmt.Errorf("non-zero exit status") - } - return nil -} - -func (p *Provisioner) mkDir(dir string) string { - switch p.config.TargetOs { - case windows: - return fmt.Sprintf("powershell /c mkdir -p '%s'", dir) - default: - return fmt.Sprintf("mkdir -p '%s'", dir) - } -} - -// uploadFile uploads a file -func (p *Provisioner) uploadFile(ui packer.Ui, comm packer.Communicator, dst, src string) error { - f, err := os.Open(src) - if err != nil { - return fmt.Errorf("Error opening: %s", err) - } - defer f.Close() - - if err = comm.Upload(dst, f, nil); err != nil { - return fmt.Errorf("Error uploading %s: %s", src, err) - } - return nil -} - -// uploadDir uploads a directory -func (p *Provisioner) uploadDir(ui packer.Ui, comm packer.Communicator, dst, src string) error { - var ignore []string - if err := p.createDir(ui, comm, dst); err != nil { - return err - } - - if src[len(src)-1] != '/' { - src = src + "/" - } - return comm.UploadDir(dst, src, ignore) -} diff --git a/provisioner/goss/packer-provisioner-goss.hcl2spec.go b/provisioner/goss/packer-provisioner-goss.hcl2spec.go deleted file mode 100644 index e6f13db..0000000 --- a/provisioner/goss/packer-provisioner-goss.hcl2spec.go +++ /dev/null @@ -1,75 +0,0 @@ -// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT. - -package goss - -import ( - "github.com/hashicorp/hcl/v2/hcldec" - "github.com/zclconf/go-cty/cty" -) - -// FlatGossConfig is an auto-generated flat version of GossConfig. -// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. -type FlatGossConfig struct { - Version *string `cty:"version" hcl:"version"` - Arch *string `cty:"arch" hcl:"arch"` - URL *string `cty:"url" hcl:"url"` - DownloadPath *string `mapstructure:"download_path" cty:"download_path" hcl:"download_path"` - Username *string `cty:"username" hcl:"username"` - Password *string `cty:"password" hcl:"password"` - SkipInstall *bool `mapstructure:"skip_install" cty:"skip_install" hcl:"skip_install"` - Inspect *bool `cty:"inspect" hcl:"inspect"` - TargetOs *string `mapstructure:"target_os" cty:"target_os" hcl:"target_os"` - Tests []string `cty:"tests" hcl:"tests"` - RetryTimeout *string `mapstructure:"retry_timeout" cty:"retry_timeout" hcl:"retry_timeout"` - Sleep *string `mapstructure:"sleep" cty:"sleep" hcl:"sleep"` - UseSudo *bool `mapstructure:"use_sudo" cty:"use_sudo" hcl:"use_sudo"` - SkipSSLChk *bool `mapstructure:"skip_ssl" cty:"skip_ssl" hcl:"skip_ssl"` - GossFile *string `mapstructure:"goss_file" cty:"goss_file" hcl:"goss_file"` - VarsFile *string `mapstructure:"vars_file" cty:"vars_file" hcl:"vars_file"` - VarsInline map[string]string `mapstructure:"vars_inline" cty:"vars_inline" hcl:"vars_inline"` - VarsEnv map[string]string `mapstructure:"vars_env" cty:"vars_env" hcl:"vars_env"` - RemoteFolder *string `mapstructure:"remote_folder" cty:"remote_folder" hcl:"remote_folder"` - RemotePath *string `mapstructure:"remote_path" cty:"remote_path" hcl:"remote_path"` - SkipDownload *bool `mapstructure:"skip_download" cty:"skip_download" hcl:"skip_download"` - Format *string `mapstructure:"format" cty:"format" hcl:"format"` - FormatOptions *string `mapstructure:"format_options" cty:"format_options" hcl:"format_options"` -} - -// FlatMapstructure returns a new FlatGossConfig. -// FlatGossConfig is an auto-generated flat version of GossConfig. -// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. -func (*GossConfig) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { - return new(FlatGossConfig) -} - -// HCL2Spec returns the hcl spec of a GossConfig. -// This spec is used by HCL to read the fields of GossConfig. -// The decoded values from this spec will then be applied to a FlatGossConfig. -func (*FlatGossConfig) HCL2Spec() map[string]hcldec.Spec { - s := map[string]hcldec.Spec{ - "version": &hcldec.AttrSpec{Name: "version", Type: cty.String, Required: false}, - "arch": &hcldec.AttrSpec{Name: "arch", Type: cty.String, Required: false}, - "url": &hcldec.AttrSpec{Name: "url", Type: cty.String, Required: false}, - "download_path": &hcldec.AttrSpec{Name: "download_path", Type: cty.String, Required: false}, - "username": &hcldec.AttrSpec{Name: "username", Type: cty.String, Required: false}, - "password": &hcldec.AttrSpec{Name: "password", Type: cty.String, Required: false}, - "skip_install": &hcldec.AttrSpec{Name: "skip_install", Type: cty.Bool, Required: false}, - "inspect": &hcldec.AttrSpec{Name: "inspect", Type: cty.Bool, Required: false}, - "target_os": &hcldec.AttrSpec{Name: "target_os", Type: cty.String, Required: false}, - "tests": &hcldec.AttrSpec{Name: "tests", Type: cty.List(cty.String), Required: false}, - "retry_timeout": &hcldec.AttrSpec{Name: "retry_timeout", Type: cty.String, Required: false}, - "sleep": &hcldec.AttrSpec{Name: "sleep", Type: cty.String, Required: false}, - "use_sudo": &hcldec.AttrSpec{Name: "use_sudo", Type: cty.Bool, Required: false}, - "skip_ssl": &hcldec.AttrSpec{Name: "skip_ssl", Type: cty.Bool, Required: false}, - "goss_file": &hcldec.AttrSpec{Name: "goss_file", Type: cty.String, Required: false}, - "vars_file": &hcldec.AttrSpec{Name: "vars_file", Type: cty.String, Required: false}, - "vars_inline": &hcldec.AttrSpec{Name: "vars_inline", Type: cty.Map(cty.String), Required: false}, - "vars_env": &hcldec.AttrSpec{Name: "vars_env", Type: cty.Map(cty.String), Required: false}, - "remote_folder": &hcldec.AttrSpec{Name: "remote_folder", Type: cty.String, Required: false}, - "remote_path": &hcldec.AttrSpec{Name: "remote_path", Type: cty.String, Required: false}, - "skip_download": &hcldec.AttrSpec{Name: "skip_download", Type: cty.Bool, Required: false}, - "format": &hcldec.AttrSpec{Name: "format", Type: cty.String, Required: false}, - "format_options": &hcldec.AttrSpec{Name: "format_options", Type: cty.String, Required: false}, - } - return s -} diff --git a/provisioner/goss/packer-provisioner-goss_test.go b/provisioner/goss/packer-provisioner-goss_test.go deleted file mode 100644 index 5104c84..0000000 --- a/provisioner/goss/packer-provisioner-goss_test.go +++ /dev/null @@ -1,274 +0,0 @@ -//go:generate packer-sdc mapstructure-to-hcl2 -type GossConfig - -package goss - -import ( - "reflect" - "testing" - - "github.com/hashicorp/packer-plugin-sdk/template/interpolate" -) - -func fakeContext() interpolate.Context { - var data map[interface{}]interface{} - var funcs map[string]interface{} - var userVars map[string]string - var sensitiveVars []string - return interpolate.Context{ - Data: data, - Funcs: funcs, - UserVariables: userVars, - SensitiveVariables: sensitiveVars, - EnableEnv: false, - BuildName: "", - BuildType: "", - TemplatePath: "", - } -} - -func TestProvisioner_Prepare(t *testing.T) { - - var tests = []struct { - name string - input []interface{} - wantErr bool - wantConfig GossConfig - }{ - { - name: "defaults", - input: []interface{}{ - map[string]interface{}{ - "tests": []string{"../../example/goss"}, - }, - }, - wantErr: false, - wantConfig: GossConfig{ - Version: "0.4.2", - Arch: "amd64", - URL: "https://github.com/goss-org/goss/releases/download/v0.4.2/goss-linux-amd64", - DownloadPath: "/tmp/goss-0.4.2-linux-amd64", - Username: "", - Password: "", - SkipInstall: false, - Inspect: false, - TargetOs: "Linux", - Tests: []string{"../../example/goss"}, - RetryTimeout: "", - Sleep: "", - UseSudo: false, - SkipSSLChk: false, - GossFile: "", - VarsFile: "", - VarsInline: nil, - VarsEnv: nil, - RemoteFolder: "/tmp", - RemotePath: "/tmp/goss", - Format: "", - FormatOptions: "", - ctx: fakeContext(), - }, - }, - { - name: "Windows", - input: []interface{}{ - map[string]interface{}{ - "tests": []string{"../../example/goss"}, - "target_os": "Windows", - "vars_env": map[string]string{ - "GOSS_USE_ALPHA": "1", - }, - }, - }, - wantErr: false, - wantConfig: GossConfig{ - Version: "0.4.2", - Arch: "amd64", - URL: "https://github.com/goss-org/goss/releases/download/v0.4.2/goss-alpha-windows-amd64.exe", - DownloadPath: "/tmp/goss-0.4.2-windows-amd64.exe", - Username: "", - Password: "", - SkipInstall: false, - Inspect: false, - TargetOs: "Windows", - Tests: []string{"../../example/goss"}, - RetryTimeout: "", - Sleep: "", - UseSudo: false, - SkipSSLChk: false, - GossFile: "", - VarsFile: "", - VarsInline: nil, - VarsEnv: map[string]string{ - "GOSS_USE_ALPHA": "1", - }, - RemoteFolder: "/tmp", - RemotePath: "/tmp/goss", - Format: "", - FormatOptions: "", - ctx: fakeContext(), - }, - }, - { - name: "Windows non alpha", - input: []interface{}{ - map[string]interface{}{ - "tests": []string{"../../example/goss"}, - "target_os": "Windows", - }, - }, - wantErr: false, - wantConfig: GossConfig{ - Version: "0.4.2", - Arch: "amd64", - URL: "https://github.com/goss-org/goss/releases/download/v0.4.2/goss-windows-amd64.exe", - DownloadPath: "/tmp/goss-0.4.2-windows-amd64.exe", - Username: "", - Password: "", - SkipInstall: false, - Inspect: false, - TargetOs: "Windows", - Tests: []string{"../../example/goss"}, - RetryTimeout: "", - Sleep: "", - UseSudo: false, - SkipSSLChk: false, - GossFile: "", - VarsFile: "", - VarsInline: nil, - VarsEnv: nil, - RemoteFolder: "/tmp", - RemotePath: "/tmp/goss", - Format: "", - FormatOptions: "", - ctx: fakeContext(), - }, - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Provisioner{ - config: GossConfig{ - ctx: interpolate.Context{}, - }, - } - err := p.Prepare(tt.input...) - if (err != nil) != tt.wantErr { - t.Errorf("Provisioner.Prepare() error = %v, wantErr %v", err, tt.wantErr) - } - - if err == nil && !reflect.DeepEqual(p.config, tt.wantConfig) { - t.Error("configs do not match") - t.Logf("got config= %v", p.config) - t.Logf("want config= %v", tt.wantConfig) - } - - }) - } -} - -func TestProvisioner_envVars(t *testing.T) { - - tests := []struct { - name string - config GossConfig - want string - }{ - { - name: "Linux", - config: GossConfig{ - TargetOs: "Linux", - VarsEnv: map[string]string{ - "somevar": "1", - }, - }, - want: "somevar=\"1\" ", - }, - { - name: "Windows", - config: GossConfig{ - TargetOs: "Windows", - VarsEnv: map[string]string{ - "GOSS_USE_ALPHA": "1", - }, - }, - want: "set \"GOSS_USE_ALPHA=1\" && ", - }, - { - name: "no vars windows", - config: GossConfig{ - TargetOs: "Windows", - VarsEnv: map[string]string{}, - }, - want: "", - }, - { - name: "no vars linux", - config: GossConfig{ - TargetOs: "Linux", - VarsEnv: map[string]string{}, - }, - want: "", - }, - { - name: "no configured target os", - config: GossConfig{ - VarsEnv: map[string]string{ - "somevar": "1", - }, - }, - want: "somevar=\"1\" ", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Provisioner{ - config: tt.config, - } - if got := p.envVars(); got != tt.want { - t.Errorf("Provisioner.envVars() = '%v', want '%v'", got, tt.want) - } - }) - } -} - -func TestProvisioner_mkDir(t *testing.T) { - tests := []struct { - name string - config GossConfig - dir string - wantcmd string - }{ - { - name: "linux", - config: GossConfig{ - TargetOs: linux, - }, - dir: "/tmp", - wantcmd: "mkdir -p '/tmp'", - }, - { - name: "windows", - config: GossConfig{ - TargetOs: windows, - }, - dir: "/tmp", - wantcmd: "powershell /c mkdir -p '/tmp'", - }, - { - name: "no configured os", - config: GossConfig{}, - dir: "/tmp", - wantcmd: "mkdir -p '/tmp'", - }, - } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - p := &Provisioner{ - config: tt.config, - } - if got := p.mkDir(tt.dir); got != tt.wantcmd { - t.Errorf("Provisioner.mkDir() = %v, want %v", got, tt.wantcmd) - } - }) - } -} diff --git a/provisioner/goss/provisioner_goss.go b/provisioner/goss/provisioner_goss.go new file mode 100644 index 0000000..1c13b0e --- /dev/null +++ b/provisioner/goss/provisioner_goss.go @@ -0,0 +1,60 @@ +//go:generate packer-sdc mapstructure-to-hcl2 -type Config,Installation,Validate +//go:generate packer-sdc struct-markdown +package goss + +import ( + "context" + "fmt" + + "github.com/hashicorp/hcl/v2/hcldec" + "github.com/hashicorp/packer-plugin-sdk/packer" + "github.com/hashicorp/packer-plugin-sdk/template/config" + "github.com/hashicorp/packer-plugin-sdk/template/interpolate" +) + +type Config struct { + Installation Installation `mapstructure:"installation" required:"false"` + Validate Validate `mapstructrue:"validate"` + + ctx interpolate.Context +} + +// Provisioner implements a packer Provisioner. +type Provisioner struct { + config Config +} + +func (p *Provisioner) ConfigSpec() hcldec.ObjectSpec { + return p.config.FlatMapstructure().HCL2Spec() +} + +// Prepare gets the Goss Provisioner ready to run. +func (p *Provisioner) Prepare(raws ...interface{}) error { + err := config.Decode(&p.config, &config.DecodeOpts{ + Interpolate: true, + InterpolateContext: &p.config.ctx, + InterpolateFilter: &interpolate.RenderFilter{ + Exclude: []string{}, + }, + }, raws...) + if err != nil { + return err + } + + if err := ValidateBlocks(&p.config.Installation, &p.config.Validate); err != nil { + return err + } + + p.config.Validate.gossBinaryPath = p.config.Installation.DownloadPath + p.config.Validate.targetOS = p.config.Installation.OS + + return nil +} + +// Provision runs the Goss Provisioner. +func (p *Provisioner) Provision(ctx context.Context, ui packer.Ui, comm packer.Communicator, generatedData map[string]interface{}) error { + ui.Say("Starting packer provisioner goss ...") + ui.Say(fmt.Sprintf("Configured to run on target system %s/%s", p.config.Installation.OS, p.config.Installation.Arch)) + + return RunBlocks(ctx, ui, comm, &p.config.Installation, &p.config.Validate) +} diff --git a/provisioner/goss/provisioner_goss.hcl2spec.go b/provisioner/goss/provisioner_goss.hcl2spec.go new file mode 100644 index 0000000..55f0ca2 --- /dev/null +++ b/provisioner/goss/provisioner_goss.hcl2spec.go @@ -0,0 +1,121 @@ +// Code generated by "packer-sdc mapstructure-to-hcl2"; DO NOT EDIT. + +package goss + +import ( + "github.com/hashicorp/hcl/v2/hcldec" + "github.com/zclconf/go-cty/cty" +) + +// FlatConfig is an auto-generated flat version of Config. +// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. +type FlatConfig struct { + Installation *FlatInstallation `mapstructure:"installation" required:"false" cty:"installation" hcl:"installation"` + Validate *FlatValidate `mapstructrue:"validate" cty:"validate" hcl:"validate"` +} + +// FlatMapstructure returns a new FlatConfig. +// FlatConfig is an auto-generated flat version of Config. +// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. +func (*Config) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { + return new(FlatConfig) +} + +// HCL2Spec returns the hcl spec of a Config. +// This spec is used by HCL to read the fields of Config. +// The decoded values from this spec will then be applied to a FlatConfig. +func (*FlatConfig) HCL2Spec() map[string]hcldec.Spec { + s := map[string]hcldec.Spec{ + "installation": &hcldec.BlockSpec{TypeName: "installation", Nested: hcldec.ObjectSpec((*FlatInstallation)(nil).HCL2Spec())}, + "validate": &hcldec.BlockSpec{TypeName: "validate", Nested: hcldec.ObjectSpec((*FlatValidate)(nil).HCL2Spec())}, + } + return s +} + +// FlatInstallation is an auto-generated flat version of Installation. +// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. +type FlatInstallation struct { + UseSudo *bool `mapstructure:"use_sudo" cty:"use_sudo" hcl:"use_sudo"` + Version *string `mapstructure:"version" cty:"version" hcl:"version"` + Arch *string `mapstructure:"arch" cty:"arch" hcl:"arch"` + OS *string `mapstructure:"os" cty:"os" hcl:"os"` + URL *string `mapstructure:"url" cty:"url" hcl:"url"` + SkipSSL *bool `mapstructure:"skip_ssl" cty:"skip_ssl" hcl:"skip_ssl"` + DownloadPath *string `mapstructure:"download_path" cty:"download_path" hcl:"download_path"` + Username *string `mapstructure:"username" cty:"username" hcl:"username"` + Password *string `mapstructure:"password" cty:"password" hcl:"password"` + EnvVars map[string]string `mapstructure:"env_vars" cty:"env_vars" hcl:"env_vars"` + SkipInstallation *bool `mapstructure:"skip_installation" cty:"skip_installation" hcl:"skip_installation"` +} + +// FlatMapstructure returns a new FlatInstallation. +// FlatInstallation is an auto-generated flat version of Installation. +// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. +func (*Installation) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { + return new(FlatInstallation) +} + +// HCL2Spec returns the hcl spec of a Installation. +// This spec is used by HCL to read the fields of Installation. +// The decoded values from this spec will then be applied to a FlatInstallation. +func (*FlatInstallation) HCL2Spec() map[string]hcldec.Spec { + s := map[string]hcldec.Spec{ + "use_sudo": &hcldec.AttrSpec{Name: "use_sudo", Type: cty.Bool, Required: false}, + "version": &hcldec.AttrSpec{Name: "version", Type: cty.String, Required: false}, + "arch": &hcldec.AttrSpec{Name: "arch", Type: cty.String, Required: false}, + "os": &hcldec.AttrSpec{Name: "os", Type: cty.String, Required: false}, + "url": &hcldec.AttrSpec{Name: "url", Type: cty.String, Required: false}, + "skip_ssl": &hcldec.AttrSpec{Name: "skip_ssl", Type: cty.Bool, Required: false}, + "download_path": &hcldec.AttrSpec{Name: "download_path", Type: cty.String, Required: false}, + "username": &hcldec.AttrSpec{Name: "username", Type: cty.String, Required: false}, + "password": &hcldec.AttrSpec{Name: "password", Type: cty.String, Required: false}, + "env_vars": &hcldec.AttrSpec{Name: "env_vars", Type: cty.Map(cty.String), Required: false}, + "skip_installation": &hcldec.AttrSpec{Name: "skip_installation", Type: cty.Bool, Required: false}, + } + return s +} + +// FlatValidate is an auto-generated flat version of Validate. +// Where the contents of a field with a `mapstructure:,squash` tag are bubbled up. +type FlatValidate struct { + UseSudo *bool `mapstructure:"use_sudo" cty:"use_sudo" hcl:"use_sudo"` + GossFile *string `mapstructure:"goss_file" cty:"goss_file" hcl:"goss_file"` + VarsFile *string `mapstructure:"vars_file" cty:"vars_file" hcl:"vars_file"` + VarsInline map[string]string `mapstructure:"vars_inline" cty:"vars_inline" hcl:"vars_inline"` + Package *string `mapstructure:"package" cty:"package" hcl:"package"` + Loglevel *string `mapstructure:"log_level" cty:"log_level" hcl:"log_level"` + RetryTimeout *string `mapstructure:"retry_timeout" cty:"retry_timeout" hcl:"retry_timeout"` + Sleep *string `mapstructure:"sleep" cty:"sleep" hcl:"sleep"` + Format *string `mapstructure:"format" cty:"format" hcl:"format"` + OutputFile *string `mapstructure:"output_file" cty:"output_file" hcl:"output_file"` + FormatOptions *string `mapstructure:"format_options" cty:"format_options" hcl:"format_options"` + EnvVars map[string]string `mapstructure:"env_vars" cty:"env_vars" hcl:"env_vars"` +} + +// FlatMapstructure returns a new FlatValidate. +// FlatValidate is an auto-generated flat version of Validate. +// Where the contents a fields with a `mapstructure:,squash` tag are bubbled up. +func (*Validate) FlatMapstructure() interface{ HCL2Spec() map[string]hcldec.Spec } { + return new(FlatValidate) +} + +// HCL2Spec returns the hcl spec of a Validate. +// This spec is used by HCL to read the fields of Validate. +// The decoded values from this spec will then be applied to a FlatValidate. +func (*FlatValidate) HCL2Spec() map[string]hcldec.Spec { + s := map[string]hcldec.Spec{ + "use_sudo": &hcldec.AttrSpec{Name: "use_sudo", Type: cty.Bool, Required: false}, + "goss_file": &hcldec.AttrSpec{Name: "goss_file", Type: cty.String, Required: false}, + "vars_file": &hcldec.AttrSpec{Name: "vars_file", Type: cty.String, Required: false}, + "vars_inline": &hcldec.AttrSpec{Name: "vars_inline", Type: cty.Map(cty.String), Required: false}, + "package": &hcldec.AttrSpec{Name: "package", Type: cty.String, Required: false}, + "log_level": &hcldec.AttrSpec{Name: "log_level", Type: cty.String, Required: false}, + "retry_timeout": &hcldec.AttrSpec{Name: "retry_timeout", Type: cty.String, Required: false}, + "sleep": &hcldec.AttrSpec{Name: "sleep", Type: cty.String, Required: false}, + "format": &hcldec.AttrSpec{Name: "format", Type: cty.String, Required: false}, + "output_file": &hcldec.AttrSpec{Name: "output_file", Type: cty.String, Required: false}, + "format_options": &hcldec.AttrSpec{Name: "format_options", Type: cty.String, Required: false}, + "env_vars": &hcldec.AttrSpec{Name: "env_vars", Type: cty.Map(cty.String), Required: false}, + } + return s +} diff --git a/provisioner/goss/provisioner_goss_test.go b/provisioner/goss/provisioner_goss_test.go new file mode 100644 index 0000000..08b2d7f --- /dev/null +++ b/provisioner/goss/provisioner_goss_test.go @@ -0,0 +1,72 @@ +package goss + +import ( + "fmt" + "os" + "os/exec" + "testing" + + "github.com/acarl005/stripansi" + "github.com/hashicorp/packer-plugin-sdk/acctest" +) + +func TestAccGossProvisioner(t *testing.T) { + testCases := []struct { + template string + teardown func() error + err bool + }{ + { + template: "latest.pkr.hcl", + }, + { + template: "version.pkr.hcl", + }, + { + template: "vars.pkr.hcl", + }, + { + template: "format.pkr.hcl", + teardown: func() error { + if err := os.Remove("test-results.xml"); err != nil { + return err + } + + return nil + }, + }, + { + template: "included.pkr.hcl", + }, + } + + for _, tc := range testCases { + t.Run(tc.template, func(t *testing.T) { + tmpl, err := os.ReadFile(fmt.Sprintf("testdata/%s", tc.template)) + if err != nil { + t.Fatalf("Error reading template: %v", err) + } + + testCase := &acctest.PluginTestCase{ + Name: tc.template, + Template: string(tmpl), + Type: "packer-provisioner-goss", + Teardown: tc.teardown, + Check: func(buildCommand *exec.Cmd, logfile string) error { + if buildCommand.ProcessState != nil { + if buildCommand.ProcessState.ExitCode() != 0 { + b, _ := os.ReadFile(logfile) + + fmt.Println(stripansi.Strip(string(b))) + + return fmt.Errorf("Bad exit code") + } + } + return nil + }, + } + + acctest.TestPlugin(t, testCase) + }) + } +} diff --git a/provisioner/goss/testdata/format.pkr.hcl b/provisioner/goss/testdata/format.pkr.hcl new file mode 100644 index 0000000..5f2439a --- /dev/null +++ b/provisioner/goss/testdata/format.pkr.hcl @@ -0,0 +1,20 @@ +source "docker" "alpine" { + image = "alpine" + export_path = "alpine.tar" +} + +build { + sources = ["docker.alpine"] + + provisioner "goss" { + installation {} + + validate { + goss_file = "./testdata/goss.yaml" + format = "junit" + format_options = "pretty" + output_file = "test-results.xml" + } + } +} + \ No newline at end of file diff --git a/provisioner/goss/testdata/goss.yaml b/provisioner/goss/testdata/goss.yaml new file mode 100644 index 0000000..c16133d --- /dev/null +++ b/provisioner/goss/testdata/goss.yaml @@ -0,0 +1,3 @@ +package: + sshd: + installed: true \ No newline at end of file diff --git a/provisioner/goss/testdata/goss_tmpl.yaml b/provisioner/goss/testdata/goss_tmpl.yaml new file mode 100644 index 0000000..a217724 --- /dev/null +++ b/provisioner/goss/testdata/goss_tmpl.yaml @@ -0,0 +1,5 @@ +package: + {{ .Vars.pkg }}: + installed: {{ .Vars.installed }} + curl: + installed: {{ .Env.curl }} \ No newline at end of file diff --git a/provisioner/goss/testdata/gossfile_included.yaml b/provisioner/goss/testdata/gossfile_included.yaml new file mode 100644 index 0000000..bd22772 --- /dev/null +++ b/provisioner/goss/testdata/gossfile_included.yaml @@ -0,0 +1,7 @@ +package: + {{ .Vars.pkg }}: + installed: {{ .Vars.installed }} + curl: + installed: {{ .Env.installed }} +gossfile: + ./testdata/goss.yaml: {} diff --git a/provisioner/goss/testdata/included.pkr.hcl b/provisioner/goss/testdata/included.pkr.hcl new file mode 100644 index 0000000..4d2ad27 --- /dev/null +++ b/provisioner/goss/testdata/included.pkr.hcl @@ -0,0 +1,25 @@ +source "docker" "alpine" { + image = "alpine" + export_path = "alpine.tar" +} + +build { + sources = ["docker.alpine"] + + provisioner "goss" { + installation {} + + validate { + goss_file = "./testdata/gossfile_included.yaml" + vars_file = "./testdata/vars.yaml" + vars_inline = { + installed = true + } + + env_vars = { + installed = true + } + } + } +} + \ No newline at end of file diff --git a/provisioner/goss/testdata/latest.pkr.hcl b/provisioner/goss/testdata/latest.pkr.hcl new file mode 100644 index 0000000..472a3ba --- /dev/null +++ b/provisioner/goss/testdata/latest.pkr.hcl @@ -0,0 +1,16 @@ +source "docker" "alpine" { + image = "alpine" + export_path = "alpine.tar" +} + +build { + sources = ["docker.alpine"] + + provisioner "goss" { + installation {} + + validate { + goss_file = "./testdata/goss.yaml" + } + } +} \ No newline at end of file diff --git a/provisioner/goss/testdata/vars.pkr.hcl b/provisioner/goss/testdata/vars.pkr.hcl new file mode 100644 index 0000000..f2592c8 --- /dev/null +++ b/provisioner/goss/testdata/vars.pkr.hcl @@ -0,0 +1,23 @@ +source "docker" "alpine" { + image = "alpine" + export_path = "alpine.tar" +} + +build { + sources = ["docker.alpine"] + provisioner "goss" { + installation {} + validate { + goss_file = "./testdata/goss_tmpl.yaml" + + vars_file = "./testdata/vars.yaml" + vars_inline = { + installed = true + } + + env_vars = { + curl = true + } + } + } +} \ No newline at end of file diff --git a/provisioner/goss/testdata/vars.yaml b/provisioner/goss/testdata/vars.yaml new file mode 100644 index 0000000..fd7b3db --- /dev/null +++ b/provisioner/goss/testdata/vars.yaml @@ -0,0 +1 @@ +pkg: ansible \ No newline at end of file diff --git a/provisioner/goss/testdata/version.pkr.hcl b/provisioner/goss/testdata/version.pkr.hcl new file mode 100644 index 0000000..61da9bd --- /dev/null +++ b/provisioner/goss/testdata/version.pkr.hcl @@ -0,0 +1,19 @@ +source "docker" "alpine" { + image = "alpine" + export_path = "alpine.tar" +} + +build { + sources = ["docker.alpine"] + + provisioner "goss" { + installation { + version = "0.4.2" + } + + validate { + goss_file = "./testdata/goss.yaml" + } + } +} + \ No newline at end of file diff --git a/provisioner/goss/types.go b/provisioner/goss/types.go new file mode 100644 index 0000000..bcdbdf6 --- /dev/null +++ b/provisioner/goss/types.go @@ -0,0 +1,54 @@ +package goss + +const ( + // Install + Linux = "Linux" + Windows = "Windows" + DefaultArch = "amd64" + DefaultOS = Linux + Latest = "latest" + + // LatestVersionDownloadURL . + LatestVersionDownloadURL = "https://github.com/goss-org/goss/releases/latest/download/goss-%s-%s" + + // VersionDownloadURL . + VersionDownloadURL = "https://github.com/goss-org/goss/releases/download/v%s/goss-%s-%s" + + // DefaultDownloadPath /tmp/goss---. + DefaultDownloadPath = "/tmp/goss-%s-%s-%s" + + // DownloadCmd || . + DownloadCmd = "%s %s curl -sL %s %s -o %s %s || %s %s wget -q %s %s -O %s %s" + + // InstallCmd < goss binary path> . + InstallCmd = "chmod 555 %s && %s --version" + + // Render + // . + // RenderCmd = "cd %s && %s %s %s %s %s %s render %s > %s" + + // // DefaultGossFile . + // DefaultGossSpecFile = "./goss-spec.yaml" + DefaultGossFile = "./goss.yaml" + + // Validate + // . + ValidateCmd = "%s %s %s %s %s %s %s %s validate --retry-timeout=%s --sleep=%s %s %s %s" + + // mkDirCmd + mkDirCmd = "mkdir -p %s" + + DefaultSleep = "1s" + DefaultRetryTimeout = "0s" + + // We dont expose the RemotePath in the validate block so we avoid confusing user with directories and force them to always use absolute paths + DefaultRemotePath = "/tmp" +) + +var ( + validOS = []string{Linux, Windows} + ValidFormats = []string{"documentation", "json", "json_oneline", "junit", "nagios", "nagios_verbose", "rspecish", "silent", "tap"} + ValidFormatOptions = []string{"perfdata", "verbose", "pretty"} + ValidPackageTypes = []string{"apk", "dpkg", "pacman", "rpm"} + validLogLevel = []string{"TRACE", "DEBUG", "INFO", "WARN", "ERROR"} +) diff --git a/provisioner/goss/utils.go b/provisioner/goss/utils.go new file mode 100644 index 0000000..77bef18 --- /dev/null +++ b/provisioner/goss/utils.go @@ -0,0 +1,67 @@ +package goss + +import ( + "fmt" + "os" + "slices" + "strings" + + "github.com/hashicorp/packer-plugin-sdk/packer" +) + +func DownloadFile(comm packer.Communicator, src, dst string) error { + f, err := os.Create(dst) + if err != nil { + return fmt.Errorf("error opening \"%s\": %w", dst, err) + } + + defer f.Close() + + if err := comm.Download(src, f); err != nil { + return fmt.Errorf("error downloading \"%s\": %w", src, err) + } + + return nil +} + +// SanitizeCommands removes any extra spaces from a string. +func SanitizeCommands(s string) string { + return strings.Join(strings.Fields(s), " ") +} + +// ExportEnvVars outputs a command string of environment variables. +func ExportEnvVars(v map[string]string, os string) string { + if len(v) == 0 { + return "" + } + + envs := "" + keys := MapKeys(v) + slices.Sort(keys) + + for k, v := range v { + if os == Windows { + // Windows requires a call to "set" as separate command separated by && for each env variable + envs += fmt.Sprintf("set %s=%s && ", k, v) + } else if os == Linux { + envs += fmt.Sprintf("%s=%s ", k, v) + } + } + + if os == Windows { + return envs + } + + return "export " + envs + ";" +} + +// MapKeys returns the keys of a map as a slice. +func MapKeys(m map[string]string) []string { + keys := make([]string, 0, len(m)) + + for k := range m { + keys = append(keys, k) + } + + return keys +} diff --git a/tools/tools.go b/tools/tools.go new file mode 100644 index 0000000..b38d773 --- /dev/null +++ b/tools/tools.go @@ -0,0 +1,23 @@ +//go:build tools + +package tools + +// https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module + +//go:generate go install github.com/golangci/golangci-lint/cmd/golangci-lint +//go:generate go install mvdan.cc/gofumpt +//go:generate go install github.com/daixiang0/gci +//go:generate go install gotest.tools/gotestsum +//go:generate go install github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc +import ( + // gci + _ "github.com/daixiang0/gci" + // golangci-lint + _ "github.com/golangci/golangci-lint/cmd/golangci-lint" + // packer-plugin-sdk + _ "github.com/hashicorp/packer-plugin-sdk/cmd/packer-sdc" + // gotestsum + _ "gotest.tools/gotestsum" + // gofumpt + _ "mvdan.cc/gofumpt" +)