From 74cb2dc12b5a83ddad8078bbbf5163b9b08413ef Mon Sep 17 00:00:00 2001 From: Keith Schmitt <32067685+schmikei@users.noreply.github.com> Date: Fri, 14 Apr 2023 12:31:59 -0600 Subject: [PATCH] Remove metric scrape interval (#3) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove metric scrape interval as it should be up to the invoker how to run * feat: add gh workflows (#265) * Bump github.com/BurntSushi/toml from 1.2.0 to 1.2.1 (#271) Bumps [github.com/BurntSushi/toml](https://github.com/BurntSushi/toml) from 1.2.0 to 1.2.1. - [Release notes](https://github.com/BurntSushi/toml/releases) - [Commits](https://github.com/BurntSushi/toml/compare/v1.2.0...v1.2.1) --- updated-dependencies: - dependency-name: github.com/BurntSushi/toml dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump github.com/prometheus/exporter-toolkit from 0.7.3 to 0.8.2 (#272) Bumps [github.com/prometheus/exporter-toolkit](https://github.com/prometheus/exporter-toolkit) from 0.7.3 to 0.8.2. - [Release notes](https://github.com/prometheus/exporter-toolkit/releases) - [Changelog](https://github.com/prometheus/exporter-toolkit/blob/master/CHANGELOG.md) - [Commits](https://github.com/prometheus/exporter-toolkit/compare/v0.7.3...v0.8.2) --- updated-dependencies: - dependency-name: github.com/prometheus/exporter-toolkit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump github.com/prometheus/client_golang from 1.13.0 to 1.14.0 (#274) Bumps [github.com/prometheus/client_golang](https://github.com/prometheus/client_golang) from 1.13.0 to 1.14.0. - [Release notes](https://github.com/prometheus/client_golang/releases) - [Changelog](https://github.com/prometheus/client_golang/blob/main/CHANGELOG.md) - [Commits](https://github.com/prometheus/client_golang/compare/v1.13.0...v1.14.0) --- updated-dependencies: - dependency-name: github.com/prometheus/client_golang dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump github.com/prometheus/common from 0.37.0 to 0.39.0 (#273) Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.37.0 to 0.39.0. - [Release notes](https://github.com/prometheus/common/releases) - [Commits](https://github.com/prometheus/common/compare/v0.37.0...v0.39.0) --- updated-dependencies: - dependency-name: github.com/prometheus/common dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * fix: Fixed github action runs against forked repos (#280) * chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint fix: fix typo fix: fix typo chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint fix: fix typo * chore: savepoint chore: savepoint feat: test gh action pr-cleanup (#2) * feat: test gh action pr-cleanup * chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint * chore: savepoint * chore: savepoint * chore: savepoint * chore: savepoint * chore: savepoint * chore: savepoint * chore: savepoint * feat: do a release 0.4.1 (#3) * chore: savepoint * chore: savepoint * chore: savepoint * feat: do a release 0.4.2 (#4) * chore: savepoint * chore: savepoint (#5) * chore: savepoint * chore: savepoint * chore: savepoint * feat: do release 0.4.4 (#6) * feat: do a release 0.4.4 * chore: savepoint * chore: savepoint * chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint chore: savepoint * fix: fix GitHub release failed with status: 403 (#282) * Fix 0.4.0 compilation problem (#277) * Fix parsing kingpin flags according to exporter-toolkit v0.8.2 Fixes iamseth/oracledb_exporter#275 Signed-off-by: Nikolay Pelov * Update README file to reflect the changed options from exporter-toolkit. * Update release version to 0.4.1 --------- Signed-off-by: Nikolay Pelov * Improve logging after the switch to github.com/go-kit/kit/log (#278) Signed-off-by: Nikolay Pelov * refact: refact PR/release github-actions (#286) * refact: refact PR github action a bit * chore: savepoint * chore: savepoint * Caiwc/multi target (#234) * feat(): support scrape multi target rebase branch && update Makefile version * add multi-target explain to readme * docs: correct dns example port of readme --------- Co-authored-by: wccai Co-authored-by: wccai * README: add example of image hosted on github image registry * Bump golang.org/x/net from 0.4.0 to 0.7.0 (#290) Bumps [golang.org/x/net](https://github.com/golang/net) from 0.4.0 to 0.7.0. - [Release notes](https://github.com/golang/net/releases) - [Commits](https://github.com/golang/net/compare/v0.4.0...v0.7.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump github.com/prometheus/common from 0.39.0 to 0.40.0 (#291) Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.39.0 to 0.40.0. - [Release notes](https://github.com/prometheus/common/releases) - [Commits](https://github.com/prometheus/common/compare/v0.39.0...v0.40.0) --- updated-dependencies: - dependency-name: github.com/prometheus/common dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump github.com/prometheus/common from 0.40.0 to 0.41.0 (#292) Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.40.0 to 0.41.0. - [Release notes](https://github.com/prometheus/common/releases) - [Commits](https://github.com/prometheus/common/compare/v0.40.0...v0.41.0) --- updated-dependencies: - dependency-name: github.com/prometheus/common dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump github.com/prometheus/exporter-toolkit from 0.8.2 to 0.9.0 (#294) Bumps [github.com/prometheus/exporter-toolkit](https://github.com/prometheus/exporter-toolkit) from 0.8.2 to 0.9.0. - [Release notes](https://github.com/prometheus/exporter-toolkit/releases) - [Changelog](https://github.com/prometheus/exporter-toolkit/blob/master/CHANGELOG.md) - [Commits](https://github.com/prometheus/exporter-toolkit/compare/v0.8.2...v0.9.0) --- updated-dependencies: - dependency-name: github.com/prometheus/exporter-toolkit dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump github.com/prometheus/exporter-toolkit from 0.9.0 to 0.9.1 (#295) Bumps [github.com/prometheus/exporter-toolkit](https://github.com/prometheus/exporter-toolkit) from 0.9.0 to 0.9.1. - [Release notes](https://github.com/prometheus/exporter-toolkit/releases) - [Changelog](https://github.com/prometheus/exporter-toolkit/blob/master/CHANGELOG.md) - [Commits](https://github.com/prometheus/exporter-toolkit/compare/v0.9.0...v0.9.1) --- updated-dependencies: - dependency-name: github.com/prometheus/exporter-toolkit dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Bump github.com/prometheus/common from 0.41.0 to 0.42.0 (#296) Bumps [github.com/prometheus/common](https://github.com/prometheus/common) from 0.41.0 to 0.42.0. - [Release notes](https://github.com/prometheus/common/releases) - [Commits](https://github.com/prometheus/common/compare/v0.41.0...v0.42.0) --- updated-dependencies: - dependency-name: github.com/prometheus/common dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Fix broken link (#298) * :construction_worker: Update packages versions + clean up * Update packages versions + clean up * Use Oracle image to retrieve binaries * Use FQN for docker image * :bug: Fix oraclelinux image build * :wrench: Use a parameter to set oracle client version * remove percent and hyphen (#302) Some oracledb tables return names with % and - * try to resolve scrape interval of 0 implications * fix scrape interval nil check * fix synchronization --------- Signed-off-by: dependabot[bot] Signed-off-by: Nikolay Pelov Co-authored-by: Viktor Utkin Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Nikolay Pelov Co-authored-by: caiwc Co-authored-by: wccai Co-authored-by: wccai Co-authored-by: Yannig Perré Co-authored-by: markruler Co-authored-by: Yannig Co-authored-by: Egor Sidortsov --- .dockerignore | 1 + .github/PULL_REQUEST_TEMPLATE.md | 34 ++ .github/config/lint/errcheck.exclude.txt | 0 .github/dependabot.yml | 7 + .github/issue_template.md | 16 + .github/workflow-config.json | 20 + .../workflows/pull-request-cleanup-manual.yml | 96 ++++ .github/workflows/pull-request-cleanup.yml | 90 +++ .github/workflows/pull-request.yml | 366 ++++++++++++ .github/workflows/release.yml | 265 +++++++++ .gitignore | 2 + .golangci.yml | 177 ++++++ Dockerfile | 40 +- Makefile | 161 ++++-- README.md | 80 ++- alpine/Dockerfile | 33 +- collector/collector.go | 108 +++- collector/default_metrics.go | 1 + go.mod | 45 +- go.sum | 523 ++---------------- main.go | 36 +- operating-principles.md | 4 +- oraclelinux/Dockerfile | 37 +- 23 files changed, 1487 insertions(+), 655 deletions(-) create mode 100644 .github/PULL_REQUEST_TEMPLATE.md create mode 100644 .github/config/lint/errcheck.exclude.txt create mode 100644 .github/dependabot.yml create mode 100644 .github/issue_template.md create mode 100644 .github/workflow-config.json create mode 100644 .github/workflows/pull-request-cleanup-manual.yml create mode 100644 .github/workflows/pull-request-cleanup.yml create mode 100644 .github/workflows/pull-request.yml create mode 100644 .github/workflows/release.yml create mode 100644 .golangci.yml diff --git a/.dockerignore b/.dockerignore index 2e00ef48..5f34aa73 100644 --- a/.dockerignore +++ b/.dockerignore @@ -3,6 +3,7 @@ alpline .* tests *-example.toml +.golangci.yml *.md *.pc dist \ No newline at end of file diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..628ee86b --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,34 @@ +# Description + + + +Fixes # (issue) + +## Type of change + +Please delete options that are not relevant. + +- [ ] Bug fix (non-breaking change which fixes an issue) +- [ ] New feature (non-breaking change which adds functionality) +- [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected) +- [ ] This change requires a documentation update + +# How Has This Been Tested? + + + + + +## Screenshots (if appropriate): + +# Checklist: + +- [ ] My code follows the style guidelines of this project +- [ ] I have performed a self-review of my own code +- [ ] I have commented my code, particularly in hard-to-understand areas +- [ ] I have made corresponding changes to the documentation +- [ ] My changes generate no new warnings +- [ ] I have added tests that prove my fix is effective or that my feature works +- [ ] New and existing unit tests pass locally with my changes +- [ ] Any dependent changes have been merged and published in downstream modules +- [ ] Updated version in Makefile respecting [semver v2](https://semver.org/spec/v2.0.0.html) diff --git a/.github/config/lint/errcheck.exclude.txt b/.github/config/lint/errcheck.exclude.txt new file mode 100644 index 00000000..e69de29b diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..ffb65e4e --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,7 @@ +version: 2 +updates: + - package-ecosystem: "gomod" + directory: "/" + schedule: + # Check for updates to GitHub Actions every weekday + interval: "daily" diff --git a/.github/issue_template.md b/.github/issue_template.md new file mode 100644 index 00000000..6682786d --- /dev/null +++ b/.github/issue_template.md @@ -0,0 +1,16 @@ +## I'm submitting a ... + +- [ ] bug report +- [ ] feature request + +## What is the current behavior? + +## If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem + +## What is the expected behavior? + +## What is the motivation / use case for changing the behavior? + +## Please tell us about your environment: + +Version: X.Y.Z diff --git a/.github/workflow-config.json b/.github/workflow-config.json new file mode 100644 index 00000000..d419d6c2 --- /dev/null +++ b/.github/workflow-config.json @@ -0,0 +1,20 @@ +{ + "go-version": "1.19.4", + "deploy": { + "pull-request": true, + "sign-docker-image": false, + "pull-request-images": [ + { + "name": "ubuntu" + } + ], + "release-images": [ + { + "name": "ubuntu" + }, + { + "name": "oraclelinux" + } + ] + } +} diff --git a/.github/workflows/pull-request-cleanup-manual.yml b/.github/workflows/pull-request-cleanup-manual.yml new file mode 100644 index 00000000..0789222e --- /dev/null +++ b/.github/workflows/pull-request-cleanup-manual.yml @@ -0,0 +1,96 @@ +name: "[Manual] Pull Request Cleanup" + +on: + workflow_dispatch: + inputs: + pattern: + description: | + Tags pattern filter + required: true + type: string + default: "rc.pr-" + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +permissions: + contents: write + packages: write + +env: + PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} + PULL_REQUEST_BRANCH: ${{ github.head_ref }} + IMAGE_NAME: "ghcr.io/${{ github.repository }}" + PACKAGE_NAME: oracledb_exporter + PACKAGE_TYPE: container + USERNAME: ${{ github.repository_owner }} + +jobs: + cleanup-ghcr: + runs-on: ubuntu-latest + name: "cleanup ghcr / ${{ github.event.inputs.pattern }}" + steps: + - name: Cleanup versions + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FILTER: ${{ github.event.inputs.pattern }} + run: | + gh api \ + -H "Accept: application/vnd.github+json" \ + "/users/${{ env.USERNAME }}/packages/${{ env.PACKAGE_TYPE }}/${{ env.PACKAGE_NAME }}/versions" > versions.json + + VERSIONS=$(jq -r '.[] | select(.metadata.container.tags[] | test("${{ env.FILTER }}")) | .id' versions.json) + for VERSION in $(echo -n "$VERSIONS") + do + TAG=$(jq -r \ + --arg VERSION "$VERSION" \ + '.[] | select(.id | tostring | test($VERSION)) | .metadata.container.tags | join(",")' \ + versions.json + ) + DIGEST=$(jq -r \ + --arg VERSION "$VERSION" \ + '.[] | select(.id | tostring | test($VERSION)) | .name' \ + versions.json + ) + echo "deleting ${IMAGE_NAME}:${TAG} with digest=${DIGEST}" + echo "deleting package PACKAGE_VERSION_ID=${VERSION}" + # https://github.com/cli/cli/issues/3937 + echo -n | gh api \ + --silent \ + --method DELETE \ + -H "Accept: application/vnd.github+json" \ + "/users/${{ env.USERNAME }}/packages/${{ env.PACKAGE_TYPE }}/${{ env.PACKAGE_NAME }}/versions/$VERSION" \ + --input - + done + cleanup-pre-releases: + runs-on: ubuntu-latest + name: "cleanup pre-releases / ${{ github.event.inputs.pattern }}" + steps: + - name: Cleanup releases + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FILTER: ${{ github.event.inputs.pattern }} + run: | + gh api \ + -H "Accept: application/vnd.github+json" \ + "/repos/${{ github.repository }}/releases" \ + --jq='.[] | select(.prerelease=false) | select(.tag_name | test("${{ env.FILTER }}"))' > versions.json + + VERSIONS=$(jq -r '.id' versions.json) + for VERSION in $(echo -n "$VERSIONS") + do + RELEASE=$(jq -r \ + --arg VERSION "$VERSION" \ + 'select(.id | tostring | test($VERSION)) | .name' \ + versions.json + ) + echo "deleting release \"$RELEASE\" with RELEASE_ID=${VERSION}" + # https://github.com/cli/cli/issues/3937 + echo -n | gh api \ + --silent \ + --method DELETE \ + -H "Accept: application/vnd.github+json" \ + "/repos/${{ github.repository }}/releases/$VERSION" \ + --input - + done \ No newline at end of file diff --git a/.github/workflows/pull-request-cleanup.yml b/.github/workflows/pull-request-cleanup.yml new file mode 100644 index 00000000..373576e2 --- /dev/null +++ b/.github/workflows/pull-request-cleanup.yml @@ -0,0 +1,90 @@ +name: Pull Request Cleanup + +on: + pull_request: + types: [closed] + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +env: + PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} + PULL_REQUEST_BRANCH: ${{ github.head_ref }} + IMAGE_NAME: "ghcr.io/${{ github.repository }}" + PACKAGE_NAME: oracledb_exporter + PACKAGE_TYPE: container + USERNAME: ${{ github.repository_owner }} + +permissions: + contents: write + packages: write + +jobs: + cleanup-ghcr: + runs-on: ubuntu-latest + name: "cleanup ghcr" + steps: + - name: Cleanup versions + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FILTER: rc.pr-${{ env.PULL_REQUEST_NUMBER }} + run: | + gh api \ + -H "Accept: application/vnd.github+json" \ + "/users/${{ env.USERNAME }}/packages/${{ env.PACKAGE_TYPE }}/${{ env.PACKAGE_NAME }}/versions" > versions.json + + VERSIONS=$(jq -r '.[] | select(.metadata.container.tags[] | test("${{ env.FILTER }}")) | .id' versions.json) + for VERSION in $(echo -n "$VERSIONS") + do + TAG=$(jq -r \ + --arg VERSION "$VERSION" \ + '.[] | select(.id | tostring | test($VERSION)) | .metadata.container.tags | join(",")' \ + versions.json + ) + DIGEST=$(jq -r \ + --arg VERSION "$VERSION" \ + '.[] | select(.id | tostring | test($VERSION)) | .name' \ + versions.json + ) + echo "deleting ${IMAGE_NAME}:${TAG} with digest=${DIGEST}" + echo "deleting package PACKAGE_VERSION_ID=${VERSION}" + # https://github.com/cli/cli/issues/3937 + echo -n | gh api \ + --silent \ + --method DELETE \ + -H "Accept: application/vnd.github+json" \ + "/users/${{ env.USERNAME }}/packages/${{ env.PACKAGE_TYPE }}/${{ env.PACKAGE_NAME }}/versions/$VERSION" \ + --input - + done + cleanup-pre-releases: + runs-on: ubuntu-latest + name: "cleanup pre-releases" + steps: + - name: Cleanup releases + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FILTER: rc.pr-${{ env.PULL_REQUEST_NUMBER }} + run: | + gh api \ + -H "Accept: application/vnd.github+json" \ + "/repos/${{ github.repository }}/releases" \ + --jq='.[] | select(.prerelease=false) | select(.tag_name | test("${{ env.FILTER }}"))' > versions.json + + VERSIONS=$(jq -r '.id' versions.json) + for VERSION in $(echo -n "$VERSIONS") + do + RELEASE=$(jq -r \ + --arg VERSION "$VERSION" \ + 'select(.id | tostring | test($VERSION)) | .name' \ + versions.json + ) + echo "deleting release \"$RELEASE\" with RELEASE_ID=${VERSION}" + # https://github.com/cli/cli/issues/3937 + echo -n | gh api \ + --silent \ + --method DELETE \ + -H "Accept: application/vnd.github+json" \ + "/repos/${{ github.repository }}/releases/$VERSION" \ + --input - + done diff --git a/.github/workflows/pull-request.yml b/.github/workflows/pull-request.yml new file mode 100644 index 00000000..7999c8bf --- /dev/null +++ b/.github/workflows/pull-request.yml @@ -0,0 +1,366 @@ +name: Pull request +run-name: "${{ github.event.pull_request.title }} / [${{ github.actor }}] is testing${{ github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name && format(' from fork [{0}]', github.event.pull_request.head.repo.full_name) || format(' from current repo') }} 🚀" + +on: + pull_request: + branches: + - main + - master + paths-ignore: + - ".github/**/*.yml" + - "**/*.md" + - "README.md" + +permissions: + contents: write + packages: write + security-events: write + pull-requests: write + +concurrency: + group: ${{ github.event.pull_request.head.repo.full_name }}-${{ github.head_ref }}/${{ github.ref }} + cancel-in-progress: true + +env: + PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} + PULL_REQUEST_BRANCH: ${{ github.head_ref }} + PULL_REQUEST_HEAD: ${{ github.event.pull_request.head.sha }} + CONCURRENCY_GROUP: ${{ github.event.pull_request.head.repo.full_name }}-${{ github.head_ref }}/${{ github.ref }} + BRANCH: ${{ github.event.pull_request.head.ref }} + REPOSITORY: ${{ github.event.pull_request.head.repo.full_name }} + REGISTRY: ghcr.io + IMAGE_NAME: "ghcr.io/${{ github.repository }}" + RELEASE: false + FORKED: ${{ github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name }} + +jobs: + config: + if: github.triggering_actor != 'dependabot[bot]' + runs-on: ubuntu-latest + outputs: + go-version: ${{ fromJson(steps.config.outputs.config).go-version }} + deploy-pull-request: ${{ fromJson(steps.config.outputs.config).deploy.pull-request }} + deploy-sign-docker-image: ${{ fromJson(steps.config.outputs.config).deploy.sign-docker-image }} + deploy-pre-release-matrix: ${{ steps.pre-release-matrix.outputs.matrix }} + deploy-release-matrix: ${{ steps.release-matrix.outputs.matrix }} + is-forked: ${{ github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ env.PULL_REQUEST_HEAD }} + + - name: Read config + id: config + run: echo "config=$(jq -M -c '.' ./.github/workflow-config.json)" >> $GITHUB_OUTPUT + + - name: List Pre-release profiles + id: deploy-pr-images-profiles + run: echo "profiles=$(jq -c -M '.deploy."pull-request-images"' .github/workflow-config.json)" >> $GITHUB_OUTPUT + + - name: Deploy pre-release matrix + id: pre-release-matrix + run: echo 'matrix={"include":${{ steps.deploy-pr-images-profiles.outputs.profiles }} }' >> $GITHUB_OUTPUT + + - name: List release profiles + id: deploy-images-profiles + run: echo "profiles=$(jq -c -M '.deploy."release-images"' .github/workflow-config.json)" >> $GITHUB_OUTPUT + + - name: Deploy release matrix + id: release-matrix + run: echo 'matrix={"include":${{ steps.deploy-images-profiles.outputs.profiles }} }' >> $GITHUB_OUTPUT + + build: + runs-on: ubuntu-latest + needs: + - config + outputs: + version: ${{ steps.version.outputs.version }} + oracle-version: ${{ steps.version.outputs.oracle-version }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ env.PULL_REQUEST_HEAD }} + + - name: Setup Golang + uses: actions/setup-go@v3 + with: + go-version: ${{ needs.config.outputs.go-version }} + + - name: Get makefile versions + id: version + run: | + oracle_version=$(make oracle-version) + version=$(make version) + echo "oracle-version=$oracle_version" >> $GITHUB_OUTPUT + echo "version=$version" >> $GITHUB_OUTPUT + + - name: Setup instantclient cache + uses: actions/cache@v3 + env: + cache-name: cache-instantclient-rpm + cache-version: ${{ steps.version.outputs.oracle-version }} + with: + path: | + ./oracle-instantclient-*.rpm + ./oci8.pc + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ hashFiles('**/Makefile') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}- + + - name: Install dependencies + run: | + make oci.pc prereq + + - name: Setup Golang cache + uses: actions/cache@v3 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Build artifact + run: make go-build + + - name: Run test + run: make go-test + + - name: Go lint + continue-on-error: true + uses: golangci/golangci-lint-action@v3 + with: + args: --issues-exit-code=0 + skip-pkg-cache: true + skip-build-cache: true + + - name: Package artifact + run: | + mv dist/*.tar.gz application.tar.gz + + - name: Upload build output + uses: actions/upload-artifact@v3 + with: + name: application + path: "./application.tar.gz" + + - name: Upload test coverage + uses: actions/upload-artifact@v3 + with: + name: test-coverage + path: "./test-coverage.out" + + release: + runs-on: ubuntu-latest + needs: + - config + - build + outputs: + version: ${{ steps.version.outputs.version }} + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ env.PULL_REQUEST_HEAD }} + + - name: Set alpha version + id: version + run: echo "version=${{ needs.build.outputs.version }}-rc.pr-${{ env.PULL_REQUEST_NUMBER }}-${{ github.run_number }}" >> $GITHUB_OUTPUT + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: application + path: "." + + - name: Rename artifact + run: mv application.tar.gz ${{ github.event.repository.name }}.tar.gz + + - name: Create release + if: ${{ env.FORKED == 'false' }} + uses: softprops/action-gh-release@v1 + id: create-release + with: + name: Pre-release ${{ steps.version.outputs.version }} + tag_name: ${{ steps.version.outputs.version }} + token: ${{ secrets.GITHUB_TOKEN }} + body: ${{ steps.changelog.outputs.changelog }} + files: | + ./${{ github.event.repository.name }}.tar.gz + draft: false + prerelease: true + generate_release_notes: true + + deploy: + name: deploy-[${{ matrix.name }}] + runs-on: ubuntu-latest + strategy: + max-parallel: 1 + matrix: ${{ fromJson(needs.config.outputs.deploy-pre-release-matrix) }} + if: ${{ !failure() && needs.release.result == 'success' && needs.config.outputs.deploy-pull-request == 'true' }} + needs: + - config + - build + - release + steps: + - name: Checkout + uses: actions/checkout@v3 + with: + ref: ${{ env.PULL_REQUEST_HEAD }} + + - name: Setup instantclient cache + uses: actions/cache@v3 + env: + cache-name: cache-instantclient-rpm + cache-version: ${{ needs.build.outputs.oracle-version }} + with: + path: | + ./oracle-instantclient-*.rpm + ./oci8.pc + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ hashFiles('**/Makefile') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}- + + - name: Install dependencies + run: | + make oci.pc download-rpms + + - name: Build image + id: docker-meta + env: + VERSION: "${{ needs.release.outputs.version }}" + run: | + make ${{ matrix.name }}-image + TAG_SUFFIX=$(echo "-${{ matrix.name }}" | sed s/-ubuntu//) + echo "image-id=$IMAGE_NAME" >> $GITHUB_OUTPUT + echo "image-version=${VERSION}${TAG_SUFFIX}" >> $GITHUB_OUTPUT + + - name: Log in to registry + if: ${{ env.FORKED == 'false' }} + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.REGISTRY }} -u $ --password-stdin + + - name: Push image + if: ${{ env.FORKED == 'false' }} + env: + VERSION: "${{ needs.release.outputs.version }}" + run: | + make push-${{ matrix.name }}-image + + - name: Format current time + if: ${{ env.FORKED == 'false' }} + id: time_now + run: echo "time_now_formatted=$(date +'%Y-%m-%d %H:%M:%S')" >> "$GITHUB_OUTPUT" + + - name: Find releases comment + if: ${{ env.FORKED == 'false' }} + uses: peter-evans/find-comment@v2 + id: find_comment + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: "github-actions[bot]" + body-includes: "Following docker image(s) have been created for this PR." + + - name: Create releases comment + uses: peter-evans/create-or-update-comment@v2 + if: ${{ steps.find_comment.outputs.comment-id == '' && env.FORKED == 'false' }} + with: + comment-id: ${{ steps.find_comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + edit-mode: replace + body: | + ## Pull Request information + Following docker image(s) have been created for this PR. + | Time | Tag | + | --- | --- | + | ${{ steps.time_now.outputs.time_now_formatted }} | **${{ steps.docker-meta.outputs.image-version }}** | + + - name: Append releases comment + uses: peter-evans/create-or-update-comment@v2 + if: ${{ steps.find_comment.outputs.comment-id != '' && env.FORKED == 'false' }} + with: + comment-id: ${{ steps.find_comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + edit-mode: append + body: | + | ${{ steps.time_now.outputs.time_now_formatted }} | **${{ steps.docker-meta.outputs.image-version }}** | + + - name: Setup cosign + if: ${{ needs.config.outputs.deploy-sign-docker-image == 'true' && env.FORKED == 'false' }} + uses: sigstore/cosign-installer@main + + - name: Write signing key to disk (only needed for `cosign sign --key`) + if: ${{ needs.config.outputs.deploy-sign-docker-image == 'true' && env.FORKED == 'false' }} + continue-on-error: true + run: echo "${{ secrets.SIGNING_SECRET }}" > cosign.key + + - name: Sign the published Docker image + if: ${{ needs.config.outputs.deploy-sign-docker-image == 'true' && env.FORKED == 'false' }} + continue-on-error: true + env: + COSIGN_PASSWORD: "" + VERSION: "${{ needs.release.outputs.version }}" + run: make sign-${{ matrix.name }}-image + + - name: Container scan + uses: aquasecurity/trivy-action@0.8.0 + env: + image-ref: "${{ steps.docker-meta.outputs.image-id }}:${{ steps.docker-meta.outputs.image-version }}" + with: + image-ref: "${{ env.image-ref }}" + ignore-unfixed: true + vuln-type: "os,library" + severity: "CRITICAL,HIGH" + format: "sarif" + output: "trivy-results.sarif" + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: "trivy-results.sarif" + category: trivy-${{ matrix.name }} + + comments: + runs-on: ubuntu-latest + if: ${{ needs.config.outputs.is-forked == 'false' }} + needs: + - config + - release + steps: + - name: Format current time + id: time_now + run: echo "time_now_formatted=$(date +'%Y-%m-%d %H:%M:%S')" >> "$GITHUB_OUTPUT" + + - name: Find releases comment + uses: peter-evans/find-comment@v2 + id: find_comment + with: + issue-number: ${{ github.event.pull_request.number }} + comment-author: "github-actions[bot]" + body-includes: "Following release(s) have been created for this PR." + + - name: Create releases comment + uses: peter-evans/create-or-update-comment@v2 + if: ${{ steps.find_comment.outputs.comment-id == '' }} + with: + comment-id: ${{ steps.find_comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + edit-mode: replace + body: | + ## Pull Request information + Following release(s) have been created for this PR. + | Time | Release | + | --- | --- | + | ${{ steps.time_now.outputs.time_now_formatted }} | **${{ needs.release.outputs.version }}** | + + - name: Append releases comment + uses: peter-evans/create-or-update-comment@v2 + if: ${{ steps.find_comment.outputs.comment-id != '' }} + with: + comment-id: ${{ steps.find_comment.outputs.comment-id }} + issue-number: ${{ github.event.pull_request.number }} + edit-mode: append + body: | + | ${{ steps.time_now.outputs.time_now_formatted }} | **${{ needs.release.outputs.version }}** | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 00000000..59ea4f23 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,265 @@ +name: Release + +on: + pull_request_target: + types: + - closed + branches: + - master + - main + +concurrency: + group: ${{ github.workflow }} + cancel-in-progress: false + +permissions: + contents: write + packages: write + security-events: write + +env: + PULL_REQUEST_NUMBER: ${{ github.event.pull_request.number }} + PULL_REQUEST_BRANCH: ${{ github.head_ref }} + BRANCH: ${{ github.event.pull_request.head.ref }} + REGISTRY: ghcr.io + IMAGE_NAME: "ghcr.io/${{ github.repository }}" + RELEASE: true + +jobs: + config: + if: github.triggering_actor != 'dependabot[bot]' && github.event.pull_request.merged == true + runs-on: ubuntu-latest + outputs: + go-version: ${{ fromJson(steps.config.outputs.config).go-version }} + deploy-pull-request: ${{ fromJson(steps.config.outputs.config).deploy.pull-request }} + deploy-sign-docker-image: ${{ fromJson(steps.config.outputs.config).deploy.sign-docker-image }} + deploy-pre-release-matrix: ${{ steps.pre-release-matrix.outputs.matrix }} + deploy-release-matrix: ${{ steps.release-matrix.outputs.matrix }} + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Read config + id: config + run: echo "config=$(jq -M -c '.' ./.github/workflow-config.json)" >> $GITHUB_OUTPUT + + - name: List Pre-release profiles + id: deploy-pr-images-profiles + run: echo "profiles=$(jq -c -M '.deploy."pull-request-images"' .github/workflow-config.json)" >> $GITHUB_OUTPUT + + - name: Deploy pre-release matrix + id: pre-release-matrix + run: echo 'matrix={"include":${{ steps.deploy-pr-images-profiles.outputs.profiles }} }' >> $GITHUB_OUTPUT + + - name: List release profiles + id: deploy-images-profiles + run: echo "profiles=$(jq -c -M '.deploy."release-images"' .github/workflow-config.json)" >> $GITHUB_OUTPUT + + - name: Deploy release matrix + id: release-matrix + run: echo 'matrix={"include":${{ steps.deploy-images-profiles.outputs.profiles }} }' >> $GITHUB_OUTPUT + + build: + runs-on: ubuntu-latest + needs: + - config + outputs: + version: ${{ steps.version.outputs.version }} + oracle-version: ${{ steps.version.outputs.oracle-version }} + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup Golang + uses: actions/setup-go@v3 + with: + go-version: ${{ needs.config.outputs.go-version }} + + - name: Get makefile versions + id: version + run: | + oracle_version=$(make oracle-version) + version=$(make version) + echo "oracle-version=$oracle_version" >> $GITHUB_OUTPUT + echo "version=$version" >> $GITHUB_OUTPUT + + - name: Setup instantclient cache + uses: actions/cache@v3 + env: + cache-name: cache-instantclient-rpm + cache-version: ${{ steps.version.outputs.oracle-version }} + with: + path: | + ./oracle-instantclient-*.rpm + ./oci8.pc + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ hashFiles('**/Makefile') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}- + + - name: Install dependencies + run: | + make oci.pc prereq + + - name: Setup Golang cache + uses: actions/cache@v3 + with: + path: | + ~/go/pkg/mod + ~/.cache/go-build + key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }} + restore-keys: | + ${{ runner.os }}-go- + + - name: Build artifact + run: make go-build + + - name: Run test + run: make go-test + + - name: Go lint + continue-on-error: true + uses: golangci/golangci-lint-action@v3 + with: + args: --issues-exit-code=0 + skip-pkg-cache: true + skip-build-cache: true + + - name: Package artifact + run: | + mv dist/*.tar.gz application.tar.gz + + - name: Upload build output + uses: actions/upload-artifact@v3 + with: + name: application + path: "./application.tar.gz" + + - name: Upload test coverage + uses: actions/upload-artifact@v3 + with: + name: test-coverage + path: "./test-coverage.out" + + release: + runs-on: ubuntu-latest + needs: + - config + - build + outputs: + version: ${{ steps.version.outputs.version }} + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Set releasw version + id: version + run: echo "version=${{ needs.build.outputs.version }}" >> $GITHUB_OUTPUT + + - name: Download artifact + uses: actions/download-artifact@v3 + with: + name: application + path: "." + + - name: Rename artifact + run: mv application.tar.gz ${{ github.event.repository.name }}.tar.gz + + - name: Create release + uses: softprops/action-gh-release@v1 + id: create-release + with: + name: Release ${{ steps.version.outputs.version }} + tag_name: ${{ steps.version.outputs.version }} + token: ${{ secrets.GITHUB_TOKEN }} + body: ${{ steps.changelog.outputs.changelog }} + files: | + ./${{ github.event.repository.name }}.tar.gz + draft: false + prerelease: false + generate_release_notes: true + + deploy: + name: deploy-[${{ matrix.name }}] + runs-on: ubuntu-latest + strategy: + max-parallel: 1 + matrix: ${{ fromJson(needs.config.outputs.deploy-release-matrix) }} + if: ${{ !failure() && needs.release.result == 'success' && needs.config.outputs.deploy-pull-request == 'true' }} + needs: + - config + - build + - release + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Setup instantclient cache + uses: actions/cache@v3 + env: + cache-name: cache-instantclient-rpm + cache-version: ${{ needs.build.outputs.oracle-version }} + with: + path: | + ./oracle-instantclient-*.rpm + ./oci8.pc + key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}-${{ hashFiles('**/Makefile') }} + restore-keys: | + ${{ runner.os }}-build-${{ env.cache-name }}-${{ env.cache-version }}- + + - name: Install dependencies + run: | + make oci.pc download-rpms + + - name: Build image + id: docker-meta + env: + VERSION: "${{ needs.release.outputs.version }}" + run: | + make ${{ matrix.name }}-image + TAG_SUFFIX=$(echo "-${{ matrix.name }}" | sed s/-ubuntu//) + echo "image-id=$IMAGE_NAME" >> $GITHUB_OUTPUT + echo "image-version=${VERSION}${TAG_SUFFIX}" >> $GITHUB_OUTPUT + + - name: Log in to registry + run: echo "${{ secrets.GITHUB_TOKEN }}" | docker login ${{ env.REGISTRY }} -u $ --password-stdin + + - name: Push image + env: + VERSION: "${{ needs.release.outputs.version }}" + run: | + make push-${{ matrix.name }}-image + + - name: Setup cosign + if: ${{ needs.config.outputs.deploy-sign-docker-image == 'true' }} + uses: sigstore/cosign-installer@main + + - name: Write signing key to disk (only needed for `cosign sign --key`) + if: ${{ needs.config.outputs.deploy-sign-docker-image == 'true' }} + continue-on-error: true + run: echo "${{ secrets.SIGNING_SECRET }}" > cosign.key + + - name: Sign the published Docker image + if: ${{ needs.config.outputs.deploy-sign-docker-image == 'true' }} + continue-on-error: true + env: + COSIGN_PASSWORD: "" + VERSION: "${{ needs.release.outputs.version }}" + run: make sign-${{ matrix.name }}-image + + - name: Container scan + uses: aquasecurity/trivy-action@0.8.0 + env: + image-ref: "${{ steps.docker-meta.outputs.image-id }}:${{ steps.docker-meta.outputs.image-version }}" + with: + image-ref: "${{ env.image-ref }}" + ignore-unfixed: true + vuln-type: "os,library" + severity: "CRITICAL,HIGH" + format: "sarif" + output: "trivy-results.sarif" + + - name: Upload Trivy scan results to GitHub Security tab + uses: github/codeql-action/upload-sarif@v2 + with: + sarif_file: "trivy-results.sarif" + category: trivy-${{ matrix.name }} diff --git a/.gitignore b/.gitignore index 91905101..b5e8658a 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ dist/ .idea *.apk *.pub +*.key oci8.pc +*.skip \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml new file mode 100644 index 00000000..88aa0d6e --- /dev/null +++ b/.golangci.yml @@ -0,0 +1,177 @@ +run: + # timeout for analysis, e.g. 30s, 5m, default is 1m + deadline: 2m + +linters: + disable-all: true + enable: + # Default enabled + - deadcode + - errcheck + - gosimple + - govet + - ineffassign + - staticcheck + - structcheck + - typecheck + - unused + - varcheck + + # Ours + - gocritic + - gofumpt + - goimports + - lll + - misspell + - stylecheck + - unconvert + - unparam + - gocyclo + - gocognit + - dupl + - errorlint + - bodyclose + - exhaustive + - exhaustivestruct + - gochecknoinits + - goconst + - godox + - importas + - nestif + - nolintlint + - predeclared + - testpackage + # - wrapcheck (consider adding) + fast: false + +linters-settings: + errcheck: + # report about not checking of errors in type assertions: `a := b.(MyStruct)`; + check-type-assertions: false + + # report about assignment of errors to blank identifier: `num, _ := strconv.Atoi(numStr)`; + check-blank: true + + # path to a file containing a list of functions to exclude from checking + # see https://github.com/kisielk/errcheck#excluding-functions for details + exclude: .github/config/lint/errcheck.exclude.txt + govet: + # report about shadowed variables + check-shadowing: true + gofumpt: + # Choose whether or not to use the extra rules that are disabled by default + extra-rules: true + goimports: + maligned: + # print struct with more effective memory layout or not, false by default + suggest-new: true + misspell: + # Correct spellings using locale preferences for US or UK. + # Default is to use a neutral variety of English. + # Setting locale to US will correct the British spelling of 'colour' to 'color'. + locale: US + ignore-words: + - cancelled + lll: + # max line length, lines longer will be reported. Default is 120. + # '\t' is counted as 1 character by default, and can be changed with the tab-width option + line-length: 160 + # tab width in spaces. Default to 1. + tab-width: 1 + unused: + # treat code as a program (not a library) and report unused exported identifiers; default is false. + # XXX: if you enable this setting, unused will report a lot of false-positives in text editors: + # if it's called for subdir of a project it can't find funcs usages. All text editor integrations + # with golangci-lint call it on a directory with the changed file. + check-exported: false + unparam: + gocritic: + enabled-checks: + - appendCombine + - argOrder + - assignOp + - badCond + - boolExprSimplify + - builtinShadow + - captLocal + - caseOrder + - codegenComment + - commentedOutCode + - commentedOutImport + - defaultCaseOrder + - deprecatedComment + - docStub + - dupArg + - dupBranchBody + - dupCase + - dupSubExpr + - elseif + - emptyFallthrough + - equalFold + - flagDeref + - flagName + - hexLiteral + - indexAlloc + - initClause + - methodExprCall + - nilValReturn + - octalLiteral + - offBy1 + - rangeExprCopy + - regexpMust + - sloppyLen + - stringXbytes + - switchTrue + - typeAssertChain + - typeSwitchVar + - typeUnparen + - underef + - unlambda + - unslice + - valSwap + - weakCond + + # Unused + # - unnecessaryBlock + # - yodaStyleExpr + # - appendAssign + # - commentFormatting + # - emptyStringTest + # - exitAfterDefer + # - ifElseChain + # - hugeParam + # - importShadow + # - nestingReduce + # - paramTypeCombine + # - ptrToRefParam + # - rangeValCopy + # - singleCaseSwitch + # - sloppyReassign + # - unlabelStmt + # - unnamedResult + # - wrapperFunc + staticcheck: + # Select the Go version to target. The default is '1.13'. + go: "1.19" + stylecheck: + # Select the Go version to target. The default is '1.13'. + go: "1.19" + godox: + # report any comments starting with keywords, this is useful for TODO or FIXME comments that + # might be left in the code accidentally and should be resolved before merging + keywords: + - TODO + - HACK + - FIX + - FIXME + - TEMP + - TMP + nolintlint: + # Disable to ensure that nolint directives don't have a leading space. Default is true. + allow-leading-space: false + # Exclude following linters from requiring an explanation. Default is []. + allow-no-explanation: [errcheck] + # Enable to require an explanation of nonzero length after each nolint directive. Default is false. + require-explanation: true + # Enable to require nolint directives to mention the specific linter being suppressed. Default is false. + require-specific: true diff --git a/Dockerfile b/Dockerfile index 5aa76dc2..b28d23c0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,4 +1,10 @@ -FROM golang:1.19 AS build +# Can't use a variable to refer to external image directly with COPY. +# So using image in a step but doing nothing +ARG ORACLE_IMAGE +FROM ${ORACLE_IMAGE} as oracle-image + +# Build is starting here +FROM docker.io/library/golang:1.19 AS build ARG ORACLE_VERSION ENV ORACLE_VERSION=${ORACLE_VERSION} @@ -6,14 +12,15 @@ ARG MAJOR_VERSION ENV MAJOR_VERSION=${MAJOR_VERSION} ENV LD_LIBRARY_PATH "/usr/lib/oracle/${MAJOR_VERSION}/client64/lib" -RUN apt-get -qq update && apt-get install --no-install-recommends -qq libaio1 rpm -COPY oracle*${ORACLE_VERSION}*.rpm / -RUN rpm -Uh --nodeps /oracle-instantclient*.x86_64.rpm && rm /*.rpm +# Retrieving binaries from oracle image +COPY --from=oracle-image /usr/lib/oracle /usr/lib/oracle +COPY --from=oracle-image /usr/share/oracle /usr/share/oracle +COPY --from=oracle-image /usr/include/oracle /usr/include/oracle COPY oci8.pc.template /usr/share/pkgconfig/oci8.pc RUN sed -i "s/@ORACLE_VERSION@/$ORACLE_VERSION/g" /usr/share/pkgconfig/oci8.pc && \ - sed -i "s/@MAJOR_VERSION@/$MAJOR_VERSION/g" /usr/share/pkgconfig/oci8.pc && \ - find /usr -name oci.pc + sed -i "s/@MAJOR_VERSION@/$MAJOR_VERSION/g" /usr/share/pkgconfig/oci8.pc && \ + find /usr -name oci.pc RUN echo $LD_LIBRARY_PATH >> /etc/ld.so.conf.d/oracle.conf && ldconfig WORKDIR /go/src/oracledb_exporter @@ -24,29 +31,30 @@ ARG VERSION ENV VERSION ${VERSION:-0.1.0} ENV PKG_CONFIG_PATH /go/src/oracledb_exporter -ENV GOOS linux -RUN go build -v -ldflags "-X main.Version=${VERSION} -s -w" +RUN GOOS=linux GOARCH=amd64 go build -v -ldflags "-X main.Version=${VERSION} -s -w" -FROM ubuntu:22.04 -LABEL authors="Seth Miller,Yannig Perré" -LABEL maintainer="Yannig Perré " +FROM docker.io/library/ubuntu:22.10 +LABEL org.opencontainers.image.authors="Seth Miller,Yannig Perré " +LABEL org.opencontainers.image.description="Oracle DB Exporter" ENV VERSION ${VERSION:-0.1.0} ENV DEBIAN_FRONTEND=noninteractive -COPY oracle-instantclient*${ORACLE_VERSION}*basic*.rpm / - +# We only need lib directory +COPY --from=build /usr/lib/oracle /usr/lib/oracle RUN apt-get -qq update && \ - apt-get -qq install --no-install-recommends tzdata libaio1 rpm -y && rpm -Uvh --nodeps /oracle*${ORACLE_VERSION}*rpm && \ - rm -f /oracle*rpm + apt-get -qq install -y --no-install-recommends tzdata libaio1 && \ + rm -rf /var/lib/apt/lists/* RUN adduser --system --uid 1000 --group appuser \ && usermod -a -G 0,appuser appuser ARG ORACLE_VERSION ENV ORACLE_VERSION=${ORACLE_VERSION} -ENV LD_LIBRARY_PATH "/usr/lib/oracle/${ORACLE_VERSION}/client64/lib" +ARG MAJOR_VERSION +ENV MAJOR_VERSION=${MAJOR_VERSION} +ENV LD_LIBRARY_PATH "/usr/lib/oracle/${MAJOR_VERSION}/client64/lib" RUN echo $LD_LIBRARY_PATH >> /etc/ld.so.conf.d/oracle.conf && ldconfig ARG LEGACY_TABLESPACE diff --git a/Makefile b/Makefile index 2002d8b3..40af827b 100644 --- a/Makefile +++ b/Makefile @@ -1,102 +1,165 @@ ARCH ?= $(shell uname -m) -GOARCH ?= $(subst x86_64,amd64,$(patsubst i%86,386,$(ARCH))) -VERSION ?= 0.4.0 +OS_TYPE ?= $(shell uname -s | tr '[:upper:]' '[:lower:]') +ARCH_TYPE ?= $(subst x86_64,amd64,$(patsubst i%86,386,$(ARCH))) +GOOS ?= $(shell go env GOOS) +GOARCH ?= $(shell go env GOARCH) +VERSION ?= 0.4.4 MAJOR_VERSION ?= 21 -MINOR_VERSION ?= 7 +MINOR_VERSION ?= 8 ORACLE_VERSION ?= $(MAJOR_VERSION).$(MINOR_VERSION) +ORACLE_IMAGE ?= ghcr.io/oracle/oraclelinux8-instantclient:$(MAJOR_VERSION) PKG_VERSION ?= $(ORACLE_VERSION).0.0.0-1.el8.$(ARCH) +GLIBC_VERSION ?= 2.35-r0 LDFLAGS := -X main.Version=$(VERSION) GOFLAGS := -ldflags "$(LDFLAGS) -s -w" RPM_VERSION ?= $(ORACLE_VERSION).0.0.0-1 ORA_RPM = oracle-instantclient-basic-$(PKG_VERSION).rpm oracle-instantclient-devel-$(PKG_VERSION).rpm LD_LIBRARY_PATH = /usr/lib/oracle/$(ORACLE_VERSION)/client64/lib BUILD_ARGS = --build-arg VERSION=$(VERSION) --build-arg ORACLE_VERSION=$(ORACLE_VERSION) \ - --build-arg MAJOR_VERSION=$(MAJOR_VERSION) + --build-arg MAJOR_VERSION=$(MAJOR_VERSION) --build-arg ORACLE_IMAGE=$(ORACLE_IMAGE) LEGACY_TABLESPACE = --build-arg LEGACY_TABLESPACE=.legacy-tablespace -DIST_DIR = oracledb_exporter.$(VERSION)-ora$(ORACLE_VERSION).linux-${GOARCH} -ARCHIVE = oracledb_exporter.$(VERSION)-ora$(ORACLE_VERSION).linux-${GOARCH}.tar.gz +DIST_DIR = oracledb_exporter-$(VERSION)-ora$(ORACLE_VERSION).$(OS_TYPE)-$(ARCH_TYPE) +ARCHIVE = oracledb_exporter-$(VERSION)-ora$(ORACLE_VERSION).$(OS_TYPE)-$(ARCH_TYPE).tar.gz IMAGE_NAME ?= iamseth/oracledb_exporter +IMAGE_ID ?= $(IMAGE_NAME):$(VERSION) +IMAGE_ID_LATEST?= $(IMAGE_NAME):latest +RELEASE ?= true export LD_LIBRARY_PATH ORACLE_VERSION +version: + @echo "$(VERSION)" + +oracle-version: + @echo "$(ORACLE_VERSION)" + %.rpm: - wget -q https://download.oracle.com/otn_software/linux/instantclient/217000/$@ + wget -q "https://download.oracle.com/otn_software/linux/instantclient/$(MAJOR_VERSION)$(MINOR_VERSION)000/$@" download-rpms: $(ORA_RPM) + @true prereq: download-rpms @echo deps sudo apt-get update - sudo apt-get install --no-install-recommends -qq libaio1 rpm - sudo rpm -Uvh --nodeps --force oracle*rpm + sudo apt-get install --no-install-recommends -qq libaio1 rpm alien + sudo alien -i oracle*.rpm || sudo rpm -Uvh --nodeps --force oracle*.rpm echo $(LD_LIBRARY_PATH) | sudo tee /etc/ld.so.conf.d/oracle.conf sudo ldconfig oci.pc: sed "s/@ORACLE_VERSION@/$(ORACLE_VERSION)/g" oci8.pc.template | \ - sed "s/@MAJOR_VERSION@/$(MAJOR_VERSION)/g" > oci8.pc + sed "s/@MAJOR_VERSION@/$(MAJOR_VERSION)/g" > oci8.pc -linux: oci.pc - @echo build linux +go-build: oci.pc + @echo "Build $(OS_TYPE)" mkdir -p ./dist/$(DIST_DIR) - PKG_CONFIG_PATH=${PWD} GOOS=linux go build $(GOFLAGS) -o ./dist/$(DIST_DIR)/oracledb_exporter + PKG_CONFIG_PATH=${PWD} GOOS=$(OS_TYPE) GOARCH=$(ARCH_TYPE) go build $(GOFLAGS) -o ./dist/$(DIST_DIR)/oracledb_exporter cp default-metrics.toml ./dist/$(DIST_DIR) (cd dist ; tar cfz $(ARCHIVE) $(DIST_DIR)) -darwin: oci.pc - @echo build darwin - mkdir -p ./dist/oracledb_exporter.$(VERSION).darwin-${GOARCH} - PKG_CONFIG_PATH=${PWD} GOOS=darwin go build $(GOFLAGS) -o ./dist/oracledb_exporter.$(VERSION).darwin-${GOARCH}/oracledb_exporter - cp default-metrics.toml ./dist/oracledb_exporter.$(VERSION).darwin-${GOARCH} - (cd dist ; tar cfz oracledb_exporter.$(VERSION).darwin-${GOARCH}.tar.gz oracledb_exporter.$(VERSION).darwin-${GOARCH}) +go-lint: + @echo "Linting codebase" + docker run --rm -v $(shell pwd):/app -v ~/.cache/golangci-lint/v1.50.1:/root/.cache -w /app golangci/golangci-lint:v1.50.1 golangci-lint run -v -local-build: linux +local-build: go-build + @true build: docker + @true deps: @PKG_CONFIG_PATH=${PWD} go get -test: - @echo test - @PKG_CONFIG_PATH=${PWD} go test $$(go list ./... | grep -v /vendor/) +go-test: + @echo "Run tests" + @PKG_CONFIG_PATH=${PWD} GOOS=$(OS_TYPE) GOARCH=$(ARCH_TYPE) go test -coverprofile="test-coverage.out" $$(go list ./... | grep -v /vendor/) clean: - rm -rf ./dist sgerrand.rsa.pub glibc-2.29-r0.apk oci8.pc + rm -rf ./dist sgerrand.rsa.pub glibc-*.apk oracle-*.rpm oci8.pc docker: ubuntu-image alpine-image oraclelinux-image push-images: - docker push $(IMAGE_NAME):$(VERSION)-oraclelinux - docker push $(IMAGE_NAME):oraclelinux - docker push $(IMAGE_NAME):$(VERSION) - docker push $(IMAGE_NAME):latest - docker push $(IMAGE_NAME):$(VERSION)-alpine - docker push $(IMAGE_NAME):alpine - -sgerrand.rsa.pub: - wget -q -O sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub + @make --no-print-directory push-ubuntu-image + @make --no-print-directory push-oraclelinux-image + @make --no-print-directory push-alpine-image -glibc-2.29-r0.apk: - wget -q -O glibc-2.29-r0.apk https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.29-r0/glibc-2.29-r0.apk +glibc.apk: + wget -q -O sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub + wget -q -O glibc-$(GLIBC_VERSION).apk https://github.com/sgerrand/alpine-pkg-glibc/releases/download/$(GLIBC_VERSION)/glibc-$(GLIBC_VERSION).apk oraclelinux-image: - docker build -f oraclelinux/Dockerfile $(BUILD_ARGS) -t "$(IMAGE_NAME):$(VERSION)-oraclelinux" . - docker build -f oraclelinux/Dockerfile $(BUILD_ARGS) $(LEGACY_TABLESPACE) -t "$(IMAGE_NAME):$(VERSION)-oraclelinux_legacy-tablespace" . - docker tag "$(IMAGE_NAME):$(VERSION)-oraclelinux" "$(IMAGE_NAME):oraclelinux" + if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect "$(IMAGE_ID)-oraclelinux" > /dev/null; then \ + echo "Image \"$(IMAGE_ID)-oraclelinux\" already exists on ghcr.io"; \ + else \ + docker build --progress=plain -f oraclelinux/Dockerfile $(BUILD_ARGS) -t "$(IMAGE_ID)-oraclelinux" . && \ + docker build --progress=plain -f oraclelinux/Dockerfile $(BUILD_ARGS) $(LEGACY_TABLESPACE) -t "$(IMAGE_ID)-oraclelinux_legacy-tablespace" . && \ + docker tag "$(IMAGE_ID)-oraclelinux" "$(IMAGE_NAME):oraclelinux"; \ + fi + +push-oraclelinux-image: + docker push $(IMAGE_ID)-oraclelinux +ifeq ("$(RELEASE)", "true") + docker push "$(IMAGE_NAME):oraclelinux" + docker push "$(IMAGE_ID)-oraclelinux_legacy-tablespace" +endif + +sign-oraclelinux-image: +ifneq ("$(wildcard cosign.key)","") + cosign sign --key cosign.key $(IMAGE_ID)-oraclelinux +else + @echo "Can't find cosign.key file" +endif ubuntu-image: $(ORA_RPM) - docker build $(BUILD_ARGS) -t "$(IMAGE_NAME):$(VERSION)" . - docker build $(BUILD_ARGS) $(LEGACY_TABLESPACE) -t "$(IMAGE_NAME):$(VERSION)_legacy-tablespace" . - docker tag "$(IMAGE_NAME):$(VERSION)" "$(IMAGE_NAME):latest" - -alpine-image: $(ORA_RPM) sgerrand.rsa.pub glibc-2.29-r0.apk - docker build -f alpine/Dockerfile $(BUILD_ARGS) -t "$(IMAGE_NAME):$(VERSION)-alpine" . - docker build -f alpine/Dockerfile $(BUILD_ARGS) $(LEGACY_TABLESPACE) -t "$(IMAGE_NAME):$(VERSION)-alpine_legacy-tablespace" . - docker tag "$(IMAGE_NAME):$(VERSION)-alpine" "$(IMAGE_NAME):alpine" - -travis: oci.pc prereq deps test linux docker + if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect "$(IMAGE_ID)" > /dev/null; then \ + echo "Image \"$(IMAGE_ID)\" already exists on ghcr.io"; \ + else \ + docker build --progress=plain $(BUILD_ARGS) -t "$(IMAGE_ID)" . && \ + docker build --progress=plain $(BUILD_ARGS) $(LEGACY_TABLESPACE) -t "$(IMAGE_ID)_legacy-tablespace" . && \ + docker tag "$(IMAGE_ID)" "$(IMAGE_ID_LATEST)"; \ + fi + +push-ubuntu-image: + docker push $(IMAGE_ID) +ifeq ("$(RELEASE)", "true") + docker push "$(IMAGE_ID_LATEST)" + docker push "$(IMAGE_ID)_legacy-tablespace" +endif + +sign-ubuntu-image: +ifneq ("$(wildcard cosign.key)","") + cosign sign --key cosign.key $(IMAGE_ID) + cosign sign --key cosign.key $(IMAGE_ID_LATEST) +else + @echo "Can't find cosign.key file" +endif + +alpine-image: $(ORA_RPM) + if DOCKER_CLI_EXPERIMENTAL=enabled docker manifest inspect "$(IMAGE_ID)-alpine" > /dev/null; then \ + echo "Image \"$(IMAGE_ID)-alpine\" already exists on ghcr.io"; \ + else \ + docker build --progress=plain -f alpine/Dockerfile $(BUILD_ARGS) -t "$(IMAGE_ID)-alpine" . && \ + docker build --progress=plain -f alpine/Dockerfile $(BUILD_ARGS) $(LEGACY_TABLESPACE) -t "$(IMAGE_ID)-alpine_legacy-tablespace" . && \ + docker tag "$(IMAGE_ID)-alpine" "$(IMAGE_NAME):alpine"; \ + fi + +push-alpine-image: + docker push $(IMAGE_ID)-alpine +ifeq ("$(RELEASE)", "true") + docker push "$(IMAGE_NAME):alpine" +endif + +sign-alpine-image: +ifneq ("$(wildcard cosign.key)","") + cosign sign --key cosign.key $(IMAGE_ID)-alpine +else + @echo "Can't find cosign.key file" +endif + +travis: oci.pc prereq deps go-test go-build docker @true -.PHONY: build deps test clean docker travis oci.pc +.PHONY: version build deps go-test clean docker travis glibc.apk oci.pc diff --git a/README.md b/README.md index 5eddbe28..c0a216b0 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ [![GoDoc](https://godoc.org/github.com/iamseth/oracledb_exporter?status.svg)](http://godoc.org/github.com/iamseth/oracledb_exporter) [![Report card](https://goreportcard.com/badge/github.com/iamseth/oracledb_exporter)](https://goreportcard.com/badge/github.com/iamseth/oracledb_exporter) -##### Table of Contents +##### Table of Contents [Description](#description) [Installation](#installation) @@ -49,11 +49,25 @@ The following metrics are exposed currently. ## Docker -You can run via Docker using an existing image. If you don't already have an Oracle server, you can run one locally in a container and then link the exporter to it. +You can run via Docker using an existing image. Since version 0.4, the images are available on the github registry. + +Here an example to retrieve the version 0.4.3: + +```bash +docker pull ghcr.io/iamseth/oracledb_exporter:0.4.3 +``` + +And here a command to run it and forward the port: + +```bash +docker run -it --rm -p 9161:9161 ghcr.io/iamseth/oracledb_exporter:0.4.3 +``` + +If you don't already have an Oracle server, you can run one locally in a container and then link the exporter to it. ```bash docker run -d --name oracle -p 1521:1521 wnameless/oracle-xe-11g-r2:18.04-apex -docker run -d --name oracledb_exporter --link=oracle -p 9161:9161 -e DATA_SOURCE_NAME=system/oracle@oracle/xe iamseth/oracledb_exporter +docker run -d --name oracledb_exporter --link=oracle -p 9161:9161 -e DATA_SOURCE_NAME=system/oracle@oracle/xe ghcr.io/iamseth/oracledb_exporter:0.4.3 ``` Since 0.2.1, the exporter image exist with Alpine flavor. Watch out for their use. It is for the moment a test. @@ -66,9 +80,9 @@ docker run -d --name oracledb_exporter --link=oracle -p 9161:9161 -e DATA_SOURCE Different Linux Distros: -* `x.y.z` - Ubuntu Linux image -* `x.y.z-oraclelinux` - Oracle Enterprise Linux image -* `x.y.z-Alpine` - Alpine Linux image +- `x.y.z` - Ubuntu Linux image +- `x.y.z-oraclelinux` - Oracle Enterprise Linux image +- `x.y.z-Alpine` - Alpine Linux image Forked Version: All the above docker images have a duplicate image tag ending in @@ -155,8 +169,6 @@ ExecStart=/usr/local/bin/oracledb_exporter \ WantedBy=multi-user.target ``` - - Then tell System D to read files: systemctl daemon-reload @@ -181,6 +193,8 @@ Usage of oracledb_exporter: File that may contain various custom metrics in a TOML file. --default.metrics string Default TOML file metrics. + --web.systemd-socket + Use systemd socket activation listeners instead of port listeners (Linux only). --web.listen-address string Address to listen on for web interface and telemetry. (default ":9161") --web.telemetry-path string @@ -189,14 +203,14 @@ Usage of oracledb_exporter: Number of maximum idle connections in the connection pool. (default "0") --database.maxOpenConns string Number of maximum open connections in the connection pool. (default "10") - --web.config - Specify which web configuration file to load + --web.config.file + Path to configuration file that can enable TLS or authentication. ``` # Default metrics This exporter comes with a set of default metrics defined in **default-metrics.toml**. You can modify this file or -provide a different one using ``default.metrics`` option. +provide a different one using `default.metrics` option. # Custom metrics @@ -204,11 +218,13 @@ provide a different one using ``default.metrics`` option. This exporter does not have the metrics you want? You can provide new one using TOML file. To specify this file to the exporter, you can: -- Use ``--custom.metrics`` flag followed by the TOML file -- Export CUSTOM_METRICS variable environment (``export CUSTOM_METRICS=my-custom-metrics.toml``) + +- Use `--custom.metrics` flag followed by the TOML file +- Export CUSTOM_METRICS variable environment (`export CUSTOM_METRICS=my-custom-metrics.toml`) This file must contain the following elements: -- One or several metric section (``[[metric]]``) + +- One or several metric section (`[[metric]]`) - For each section a context, a request and a map between a field of your request and a comment. Here's a simple example: @@ -314,10 +330,11 @@ This example allows to achieve this: ### Files & Folder: -* tns_admin folder: `/path/to/tns_admin` -* tnsnames.ora file: `/path/to/tns_admin/tnsnames.ora` +- tns_admin folder: `/path/to/tns_admin` +- tnsnames.ora file: `/path/to/tns_admin/tnsnames.ora` Example of a tnsnames.ora file: + ``` database = (DESCRIPTION = @@ -333,9 +350,9 @@ database = ### Environment Variables -* `TNS_ENTRY`: Name of the entry to use (`database` in the example file above) -* `TNS_ADMIN`: Path you choose for the tns admin folder (`/path/to/tns_admin` in the example file above) -* `DATA_SOURCE_NAME`: Datasource pointing to the `TNS_ENTRY` (`user/password@database` in the example file above) +- `TNS_ENTRY`: Name of the entry to use (`database` in the example file above) +- `TNS_ADMIN`: Path you choose for the tns admin folder (`/path/to/tns_admin` in the example file above) +- `DATA_SOURCE_NAME`: Datasource pointing to the `TNS_ENTRY` (`user/password@database` in the example file above) # TLS connection to database @@ -370,7 +387,7 @@ For more details, have a look at the following location: https://github.com/iams # Integration with Grafana -An example Grafana dashboard is available [here](https://grafana.com/dashboards/3333). +An example Grafana dashboard is available [here](https://grafana.com/grafana/dashboards/3333-oracledb/). # Build @@ -390,7 +407,7 @@ Or Alpine: ## Linux binaries -Retrieve Oracle RPMs (version 18.5): +Retrieve Oracle RPMs (version x.y): make download-rpms @@ -400,7 +417,7 @@ Then run build: ## Windows binaries -*Stollen from https://github.com/iamseth/oracledb_exporter/issues/40* +_Stollen from https://github.com/iamseth/oracledb_exporter/issues/40_ First, download Oracle Instant Client 64-Bit version basic and sdk versions. @@ -417,16 +434,16 @@ Run the MSYS2 MINGW64 terminal and set dependencies packages: - Update pacman: - pacman -Su + pacman -Su - Close terminal and open a new terminal - Update all other packages: - pacman -Su + pacman -Su - Install pkg-config and gcc: - pacman -S mingw64/mingw-w64-x86_64-pkg-config mingw64/mingw-w64-x86_64-gcc + pacman -S mingw64/mingw-w64-x86_64-pkg-config mingw64/mingw-w64-x86_64-gcc Go to the pkg-config dir **c:/msys64/mingw64/lib/pkgconfig/** and create **oci8.pc** with the following content: @@ -486,8 +503,7 @@ version as they are embedded in the container. Here an example to run this exporter (to scrap metrics from system/oracle@//host:1521/service-or-sid) and bind the exporter port (9161) to the global machine: -```docker run -it --rm -p 9161:9161 -e DATA_SOURCE_NAME=system/oracle@//host:1521/service-or-sid iamseth/oracledb_exporter:0.2.6a``` - +`docker run -it --rm -p 9161:9161 -e DATA_SOURCE_NAME=system/oracle@//host:1521/service-or-sid iamseth/oracledb_exporter:0.2.6a` ## Error scraping for wait_time @@ -497,7 +513,7 @@ If you experience an error `Error scraping for wait_time: sql: Scan error on col export NLS_LANG=AMERICAN_AMERICA.WE8ISO8859P1 export DATA_SOURCE_NAME=system/oracle@myhost -/path/to/binary --log.level error --web.listen-address 9161 +/path/to/binary --log.level error --web.listen-address :9161 ``` If using Docker, set the same variable using the -e flag. @@ -520,7 +536,6 @@ The root cause is Oracle's reaction of quering ASM-related views without ASM use $ find $ORACLE_BASE/diag/rdbms -name '*.tr[cm]' -mtime +14 -delete ``` - ## TLS and basic authentication Apache Exporter supports TLS and basic authentication. This enables better @@ -532,3 +547,10 @@ using the `--web.config` parameter. The format of the file is described Note that the TLS and basic authentication settings affect all HTTP endpoints: /metrics for scraping, /probe for probing, and the web UI. + + +## Multi-target support + +This exporter supports the multi-target pattern. This allows running a single instance of this exporter for multiple Oracle targets. + +To use the multi-target functionality, send a http request to the endpoint `/scrape?target=foo:1521` where target is set to the DSN of the Oracle instance to scrape metrics from. \ No newline at end of file diff --git a/alpine/Dockerfile b/alpine/Dockerfile index 35f7fab5..4cab27cd 100644 --- a/alpine/Dockerfile +++ b/alpine/Dockerfile @@ -1,4 +1,10 @@ -FROM golang:1.19 AS build +# Can't use a variable to refer to external image directly with COPY. +# So using image in a step but doing nothing +ARG ORACLE_IMAGE +FROM ${ORACLE_IMAGE} as oracle-image + +# Build is starting here +FROM docker.io/library/golang:1.19 AS build ARG ORACLE_VERSION ENV ORACLE_VERSION=${ORACLE_VERSION} @@ -6,14 +12,15 @@ ARG MAJOR_VERSION ENV MAJOR_VERSION=${MAJOR_VERSION} ENV LD_LIBRARY_PATH "/usr/lib/oracle/${MAJOR_VERSION}/client64/lib" -RUN apt-get -qq update && apt-get install --no-install-recommends -qq libaio1 rpm -COPY oracle*${ORACLE_VERSION}*.rpm / -RUN rpm -Uh --nodeps /oracle-instantclient*.x86_64.rpm && rm /*.rpm +# Retrieving binaries from oracle image +COPY --from=oracle-image /usr/lib/oracle /usr/lib/oracle +COPY --from=oracle-image /usr/share/oracle /usr/share/oracle +COPY --from=oracle-image /usr/include/oracle /usr/include/oracle COPY oci8.pc.template /usr/share/pkgconfig/oci8.pc RUN sed -i "s/@ORACLE_VERSION@/$ORACLE_VERSION/g" /usr/share/pkgconfig/oci8.pc && \ - sed -i "s/@MAJOR_VERSION@/$MAJOR_VERSION/g" /usr/share/pkgconfig/oci8.pc && \ - find /usr -name oci.pc + sed -i "s/@MAJOR_VERSION@/$MAJOR_VERSION/g" /usr/share/pkgconfig/oci8.pc && \ + find /usr -name oci.pc RUN echo $LD_LIBRARY_PATH >> /etc/ld.so.conf.d/oracle.conf && ldconfig WORKDIR /go/src/oracledb_exporter @@ -24,27 +31,29 @@ ARG VERSION ENV VERSION ${VERSION:-0.1.0} ENV PKG_CONFIG_PATH /go/src/oracledb_exporter -ENV GOOS linux -RUN go build -v -ldflags "-X main.Version=${VERSION} -s -w" +RUN GOOS=linux GOARCH=amd64 go build -v -ldflags "-X main.Version=${VERSION} -s -w" -FROM frolvlad/alpine-glibc:glibc-2.35 +FROM docker.io/frolvlad/alpine-glibc:glibc-2.35 LABEL authors="Seth Miller,Yannig Perré" LABEL maintainer="Yannig Perré " ENV VERSION ${VERSION:-0.1.0} -RUN apk add libaio +RUN apk add libaio --no-cache ARG LEGACY_TABLESPACE ENV LEGACY_TABLESPACE=${LEGACY_TABLESPACE} +# We only need lib directory COPY --from=build /usr/lib/oracle /usr/lib/oracle COPY --from=build /go/src/oracledb_exporter/oracledb_exporter /oracledb_exporter ADD ./default-metrics${LEGACY_TABLESPACE}.toml /default-metrics.toml ARG ORACLE_VERSION ENV ORACLE_VERSION=${ORACLE_VERSION} -ENV LD_LIBRARY_PATH "/usr/lib/oracle/${ORACLE_VERSION}/client64/lib" +ARG MAJOR_VERSION +ENV MAJOR_VERSION=${MAJOR_VERSION} +ENV LD_LIBRARY_PATH "/usr/lib/oracle/${MAJOR_VERSION}/client64/lib" RUN ldconfig "$LD_LIBRARY_PATH" ENV DATA_SOURCE_NAME system/oracle@oracle/xe @@ -53,4 +62,4 @@ RUN chmod 755 /oracledb_exporter EXPOSE 9161 -ENTRYPOINT ["/oracledb_exporter"] +ENTRYPOINT ["/oracledb_exporter"] \ No newline at end of file diff --git a/collector/collector.go b/collector/collector.go index 488bf43e..15cefcd3 100644 --- a/collector/collector.go +++ b/collector/collector.go @@ -23,8 +23,7 @@ import ( // Exporter collects Oracle DB metrics. It implements prometheus.Collector. type Exporter struct { - config *Config - + config *Config mu *sync.Mutex metricsToScrape Metrics scrapeInterval *time.Duration @@ -40,23 +39,21 @@ type Exporter struct { // Config is the configuration of the exporter type Config struct { - DSN string - MaxIdleConns int - MaxOpenConns int - CustomMetrics string - QueryTimeout int - ScrapeInterval time.Duration + DSN string + MaxIdleConns int + MaxOpenConns int + CustomMetrics string + QueryTimeout int } // CreateDefaultConfig returns the default configuration of the Exporter // it is to be of note that the DNS will be empty when func CreateDefaultConfig() *Config { return &Config{ - MaxIdleConns: 0, - MaxOpenConns: 10, - CustomMetrics: "", - QueryTimeout: 5, - ScrapeInterval: 0, + MaxIdleConns: 0, + MaxOpenConns: 10, + CustomMetrics: "", + QueryTimeout: 5, } } @@ -165,16 +162,22 @@ func (e *Exporter) Describe(ch chan<- *prometheus.Desc) { // Collect implements prometheus.Collector. func (e *Exporter) Collect(ch chan<- prometheus.Metric) { - e.mu.Lock() // ensure no simultaneous scrapes - defer e.mu.Unlock() - if e.config.ScrapeInterval == 0 { // if we are to scrape when the request is made - e.scrape(ch) - } else { - scrapeResults := e.scrapeResults // There is a risk that e.scrapeResults will be replaced while we traverse this look. This should mitigate that risk - for idx := range scrapeResults { - ch <- scrapeResults[idx] + // they are running scheduled scrapes we should only scrape new data + // on the interval + if e.scrapeInterval != nil && *e.scrapeInterval != 0 { + // read access must be checked + e.mu.Lock() + for _, r := range e.scrapeResults { + ch <- r } + e.mu.Unlock() + return } + + // otherwise do a normal scrape per request + e.mu.Lock() // ensure no simultaneous scrapes + defer e.mu.Unlock() + e.scrape(ch) ch <- e.duration ch <- e.totalScrapes ch <- e.error @@ -182,6 +185,55 @@ func (e *Exporter) Collect(ch chan<- prometheus.Metric) { ch <- e.up } +// RunScheduledScrapes is only relevant for users of this package that want to set the scrape on a timer +// rather than letting it be per Collect call +func (e *Exporter) RunScheduledScrapes(ctx context.Context, si time.Duration) { + e.scrapeInterval = &si + ticker := time.NewTicker(si) + defer ticker.Stop() + + for { + select { + case <-ticker.C: + e.mu.Lock() // ensure no simultaneous scrapes + e.scheduledScrape() + e.mu.Unlock() + case <-ctx.Done(): + return + } + } +} + +func (e *Exporter) scheduledScrape() { + metricCh := make(chan prometheus.Metric, 5) + + wg := &sync.WaitGroup{} + wg.Add(1) + go func() { + defer wg.Done() + e.scrapeResults = []prometheus.Metric{} + for { + scrapeResult, more := <-metricCh + if more { + e.scrapeResults = append(e.scrapeResults, scrapeResult) + continue + } + return + } + }() + e.scrape(metricCh) + + // report metadata metrics + metricCh <- e.duration + metricCh <- e.totalScrapes + metricCh <- e.error + e.scrapeErrors.Collect(metricCh) + metricCh <- e.up + + close(metricCh) + wg.Wait() +} + func (e *Exporter) scrape(ch chan<- prometheus.Metric) { e.totalScrapes.Inc() var err error @@ -199,13 +251,13 @@ func (e *Exporter) scrape(ch chan<- prometheus.Metric) { level.Info(e.logger).Log("Reconnecting to DB") err = e.connect() if err != nil { - level.Error(e.logger).Log("Error reconnectin to DB", err) + level.Error(e.logger).Log("Error reconnecting to DB", err) } } } + if err = e.db.Ping(); err != nil { level.Error(e.logger).Log("Error pinging oracle:", err) - // e.db.Close() e.up.Set(0) return } @@ -273,7 +325,7 @@ func (e *Exporter) connect() error { db, err := sql.Open("oracle", e.dsn) if err != nil { level.Error(e.logger).Log("Error while connecting to", e.dsn) - panic(err) + return err } level.Debug(e.logger).Log("set max idle connections to ", e.config.MaxIdleConns) db.SetMaxIdleConns(e.config.MaxIdleConns) @@ -528,3 +580,11 @@ func cleanName(s string) string { s = strings.ToLower(s) return s } + +func (e *Exporter) logError(s string) { + _ = level.Error(e.logger).Log(s) +} + +func (e *Exporter) logDebug(s string) { + _ = level.Debug(e.logger).Log(s) +} diff --git a/collector/default_metrics.go b/collector/default_metrics.go index 1a5c57dd..bfbe7e7b 100644 --- a/collector/default_metrics.go +++ b/collector/default_metrics.go @@ -7,6 +7,7 @@ import ( "github.com/go-kit/log/level" ) +// needs the const if imported, cannot os.ReadFile in this case const defaultMetricsConst = ` [[metric]] context = "sessions" diff --git a/go.mod b/go.mod index df5fa719..24489ea1 100644 --- a/go.mod +++ b/go.mod @@ -1,36 +1,39 @@ module github.com/observiq/oracledb_exporter -go 1.18 +go 1.19 require ( github.com/BurntSushi/toml v1.2.0 + github.com/alecthomas/kingpin/v2 v2.3.2 github.com/go-kit/log v0.2.1 - github.com/prometheus/client_golang v1.13.0 - github.com/prometheus/common v0.37.0 - github.com/prometheus/exporter-toolkit v0.7.3 + github.com/prometheus/client_golang v1.14.0 + github.com/prometheus/common v0.42.0 + github.com/prometheus/exporter-toolkit v0.9.1 github.com/sijms/go-ora/v2 v2.5.23 - gopkg.in/alecthomas/kingpin.v2 v2.2.6 ) require ( - github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect - github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d // indirect + github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cespare/xxhash/v2 v2.1.2 // indirect - github.com/go-logfmt/logfmt v0.5.1 // indirect - github.com/golang/protobuf v1.5.2 // indirect + github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/coreos/go-systemd/v22 v22.5.0 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect + github.com/golang/protobuf v1.5.3 // indirect github.com/jpillora/backoff v1.0.0 // indirect - github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect - github.com/pkg/errors v0.9.1 // indirect - github.com/prometheus/client_model v0.2.0 // indirect - github.com/prometheus/procfs v0.8.0 // indirect - golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 // indirect - golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect - golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b // indirect - golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a // indirect - golang.org/x/text v0.3.7 // indirect - google.golang.org/appengine v1.6.6 // indirect - google.golang.org/protobuf v1.28.1 // indirect + github.com/prometheus/client_model v0.3.0 // indirect + github.com/prometheus/procfs v0.9.0 // indirect + github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/xhit/go-str2duration/v2 v2.1.0 // indirect + golang.org/x/crypto v0.7.0 // indirect + golang.org/x/net v0.8.0 // indirect + golang.org/x/oauth2 v0.6.0 // indirect + golang.org/x/sync v0.1.0 // indirect + golang.org/x/sys v0.6.0 // indirect + golang.org/x/text v0.8.0 // indirect + google.golang.org/appengine v1.6.7 // indirect + google.golang.org/protobuf v1.30.0 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect ) diff --git a/go.sum b/go.sum index 29a994c9..9980175e 100644 --- a/go.sum +++ b/go.sum @@ -1,507 +1,90 @@ -cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= -cloud.google.com/go v0.38.0/go.mod h1:990N+gfupTy94rShfmMCWGDn0LpTmnzTp2qbd1dvSRU= -cloud.google.com/go v0.44.1/go.mod h1:iSa0KzasP4Uvy3f1mN/7PiObzGgflwredwwASm/v6AU= -cloud.google.com/go v0.44.2/go.mod h1:60680Gw3Yr4ikxnPRS/oxxkBccT6SA1yMk63TGekxKY= -cloud.google.com/go v0.45.1/go.mod h1:RpBamKRgapWJb87xiFSdk4g1CME7QZg3uwTez+TSTjc= -cloud.google.com/go v0.46.3/go.mod h1:a6bKKbmY7er1mI7TEI4lsAkts/mkhTSZK8w33B4RAg0= -cloud.google.com/go v0.50.0/go.mod h1:r9sluTvynVuxRIOHXQEHMFffphuXHOMZMycpNR5e6To= -cloud.google.com/go v0.52.0/go.mod h1:pXajvRH/6o3+F9jDHZWQ5PbGhn+o8w9qiu/CffaVdO4= -cloud.google.com/go v0.53.0/go.mod h1:fp/UouUEsRkN6ryDKNW/Upv/JBKnv6WDthjR6+vze6M= -cloud.google.com/go v0.54.0/go.mod h1:1rq2OEkV3YMf6n/9ZvGWI3GWw0VoqH/1x2nd8Is/bPc= -cloud.google.com/go v0.56.0/go.mod h1:jr7tqZxxKOVYizybht9+26Z/gUq7tiRzu+ACVAMbKVk= -cloud.google.com/go v0.57.0/go.mod h1:oXiQ6Rzq3RAkkY7N6t3TcE6jE+CIBBbA36lwQ1JyzZs= -cloud.google.com/go v0.62.0/go.mod h1:jmCYTdRCQuc1PHIIJ/maLInMho30T/Y0M4hTdTShOYc= -cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHObY= -cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= -cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= -cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= -cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= -cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= -cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/datastore v1.0.0/go.mod h1:LXYbyblFSglQ5pkeyhO+Qmw7ukd3C+pD7TKLgZqpHYE= -cloud.google.com/go/datastore v1.1.0/go.mod h1:umbIZjpQpHh4hmRpGhH4tLFup+FVzqBi1b3c64qFpCk= -cloud.google.com/go/pubsub v1.0.1/go.mod h1:R0Gpsv3s54REJCy4fxDixWD93lHJMoZTyQ2kNxGRt3I= -cloud.google.com/go/pubsub v1.1.0/go.mod h1:EwwdRX2sKPjnvnqCa270oGRyludottCI76h+R3AArQw= -cloud.google.com/go/pubsub v1.2.0/go.mod h1:jhfEVHT8odbXTkndysNHCcx0awwzvfOlguIAii9o8iA= -cloud.google.com/go/pubsub v1.3.1/go.mod h1:i+ucay31+CNRpDW4Lu78I4xXG+O1r/MAHgjpRVR+TSU= -cloud.google.com/go/storage v1.0.0/go.mod h1:IhtSnM/ZTZV8YYJWCY8RULGVqBDmpoyjwiyrjsg+URw= -cloud.google.com/go/storage v1.5.0/go.mod h1:tpKbwo567HUNpVclU5sGELwQWBDZ8gh0ZeosJ0Rtdos= -cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohlUTyfDhBk= -cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs= -cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= -dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/toml v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0= github.com/BurntSushi/toml v1.2.0/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= -github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= -github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafoB+tBA3gMyHYHrpOtNuDiK/uB5uXxq5wM= -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/alecthomas/units v0.0.0-20190924025748-f65c72e2690d h1:UQZhZ2O0vMHr2cI+DC1Mbh0TJxzA3RcLoMsFw+aXw7E= -github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= -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/alecthomas/kingpin/v2 v2.3.2 h1:H0aULhgmSzN8xQ3nX1uxtdlTHYoPLu5AhHxWrKI6ocU= +github.com/alecthomas/kingpin/v2 v2.3.2/go.mod h1:0gyi0zQnjuFk8xrkNKamJoyUo382HRL7ATRpFZCw6tE= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= 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/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE= -github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= -github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= -github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= -github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= -github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc= +github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= +github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/coreos/go-systemd/v22 v22.5.0 h1:RrqgGjYQKalulkV8NGVIfkXQf6YYmOyiJKk8iXXhfZs= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= -github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= -github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= -github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= -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-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= -github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= -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-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A= -github.com/go-logfmt/logfmt v0.5.1 h1:otpy5pqBCBZ1ng9RQ0dPu4PN7ba75Y/aA+UpowDyNVA= -github.com/go-logfmt/logfmt v0.5.1/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= -github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= -github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= -github.com/golang/mock v1.3.1/go.mod h1:sBzyDLLjw3U8JLTeZvSv8jJB+tU5PVekmnlKIyFUx0Y= -github.com/golang/mock v1.4.0/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= -github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= +github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= 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/golang/protobuf v1.3.3/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= github.com/golang/protobuf v1.3.5/go.mod h1:6O5/vntMXwX2lRkT1hjjk0nAC1IDOTvTlVgjlRvqsdk= -github.com/golang/protobuf v1.4.0-rc.1/go.mod h1:ceaxUfeHdC40wWswd/P6IGgMaK3YpKi5j83Wpe3EHw8= -github.com/golang/protobuf v1.4.0-rc.1.0.20200221234624-67d41d38c208/go.mod h1:xKAWHe0F5eneWXFV3EuXVDTCmh+JuBKY0li0aMyXATA= -github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrUpVNzEA03Pprs= -github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= -github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= -github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QDs8UjoX8= -github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= -github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= -github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= -github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -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.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.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.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= +github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= -github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= -github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= -github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200212024743-f11f1df84d12/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= -github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= -github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= -github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= -github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= -github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= -github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= -github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= -github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= -github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= -github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.3/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 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU= -github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -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/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= +github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= +github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= -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= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -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.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= -github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= -github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= -github.com/prometheus/client_golang v1.13.0 h1:b71QUfeo5M8gq2+evJdTPfZhYMAU0uKPkyPJ7TPsloU= -github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -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.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M= -github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= -github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= -github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.29.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= -github.com/prometheus/common v0.37.0 h1:ccBbHCgIiT9uSoFY0vX8H3zsNR5eLt17/RQLUvn8pXE= -github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/exporter-toolkit v0.7.3 h1:IYBn0CTGi/nYxstdTUKysuSofUNJ3DQW3FmZ/Ub6rgU= -github.com/prometheus/exporter-toolkit v0.7.3/go.mod h1:ZUBIj498ePooX9t/2xtDjeQYwvRpiPP2lh5u4iblj2g= -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.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= -github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= -github.com/prometheus/procfs v0.8.0 h1:ODq8ZFEaYeCaZOJlZZdJA2AbQR98dSHSM1KW/You5mo= -github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= +github.com/prometheus/client_golang v1.14.0 h1:nJdhIvne2eSX/XRAFV9PcvFFRbrjbcTUj0VP62TMhnw= +github.com/prometheus/client_golang v1.14.0/go.mod h1:8vpkKitgIVNcqrRBWh1C4TIUQgYNtG/XQE4E/Zae36Y= +github.com/prometheus/client_model v0.3.0 h1:UBgGFHqYdG/TPFD1B1ogZywDqEkwp3fBMvqdiQ7Xew4= +github.com/prometheus/client_model v0.3.0/go.mod h1:LDGWKZIo7rky3hgvBe+caln+Dr3dPggB5dvjtD7w9+w= +github.com/prometheus/common v0.42.0 h1:EKsfXEYo4JpWMHH5cg+KOUWeuJSov1Id8zGR8eeI1YM= +github.com/prometheus/common v0.42.0/go.mod h1:xBwqVerjNdUDjgODMpudtOMwlOwf2SaTr1yjz4b7Zbc= +github.com/prometheus/exporter-toolkit v0.9.1 h1:cNkC01riqiOS+kh3zdnNwRsbe/Blh0WwK3ij5rPJ9Sw= +github.com/prometheus/exporter-toolkit v0.9.1/go.mod h1:iFlTmFISCix0vyuyBmm0UqOUCTao9+RsAsKJP3YM9ec= +github.com/prometheus/procfs v0.9.0 h1:wzCHvIvM5SxWqYvwgVL7yJY8Lz3PKn49KQtpgMYJfhI= +github.com/prometheus/procfs v0.9.0/go.mod h1:+pB4zwohETzFnmlpe6yd2lSc+0/46IYZRB/chUwxUZY= +github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= +github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= github.com/sijms/go-ora/v2 v2.5.23 h1:b+TLHgbic5ry/LM99Rx4+17T5R9SEObltmpgRi0DKEk= github.com/sijms/go-ora/v2 v2.5.23/go.mod h1:EHxlY6x7y9HAsdfumurRfTd+v8NrEOTR3Xl4FWlH6xk= -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.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= 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/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 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= -github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= -go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= -go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ8= +github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= +github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20210915214749-c084706c2272 h1:3erb+vDS8lU1sxfDHF4/hhWyaXnhIaO+7RgL4fDZORA= -golang.org/x/crypto v0.0.0-20210915214749-c084706c2272/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= -golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= -golang.org/x/exp v0.0.0-20190829153037-c13cbed26979/go.mod h1:86+5VVa7VpoJ4kLfm080zCjGlMRFzhUhsZKEZO7MGek= -golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= -golang.org/x/exp v0.0.0-20191129062945-2f5052295587/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= -golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= -golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= -golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= -golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190409202823-959b441ac422/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190909230951-414d861bb4ac/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= -golang.org/x/lint v0.0.0-20191125180803-fdd1cda4f05f/go.mod h1:5qLYkcX4OjUUV8bRuDixDT3tpyyb+LUpUlRWLxfhWrs= -golang.org/x/lint v0.0.0-20200130185559-910be7a94367/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= -golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKGUJ2LatrhH/nqhxcFungHvyanc= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -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/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= -golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/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-20190501004415-9ce7a6920f09/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= +golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -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-20190628185345-da137c7871d7/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20190724013045-ca1201d0de80/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/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-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f h1:oA4XRj0qtSt8Yo1Zms0CUlsT3KG69V2UGQWPBxujDmc= -golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= -golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= -golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= -golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b h1:clP8eMhB30EHdc0bd2Twtq6kgU7yl5ub2cQLSdrv1Dg= -golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= -golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ= +golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= +golang.org/x/oauth2 v0.6.0 h1:Lh8GPgSKBfWSwFvtuWOfeI3aAAnbXTSutYxJiOJFgIw= +golang.org/x/oauth2 v0.6.0/go.mod h1:ycmewcwgD4Rpr3eZJLSB4Kyyljb3qDh40vJ8STE5HKw= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/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-20200317015054-43a5402ce75a/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-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/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/sync v0.1.0 h1:wsuoTGHzEhffawBOhz5CYhcrV4IdKZbEyZjBMuTp12o= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -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-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200122134326-e047566fdf82/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/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-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a h1:dGzPydgVsqGcTRVwiLJ1jVbufYwmzD3LfVPLKsKg+0k= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/sys v0.6.0 h1:MVltZSvRTcU2ljQOhs94SXPftV6DCNnZViHeQps87pQ= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/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 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= -golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/text v0.8.0 h1:57P1ETyNKtuIjB4SRd15iJxuhj8Gc416Y78H3qgMh68= +golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= -golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190425150028-36563e24a262/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190506145303-2d16b83fe98c/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= -golang.org/x/tools v0.0.0-20190606124116-d0a3d012864b/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190628153133-6cdbf07be9d0/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -golang.org/x/tools v0.0.0-20190816200558-6889da9d5479/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20190911174233-4f2ddba30aff/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191115202509-3a792d9c32b2/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-20191125144606-a911d9008d1f/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191130070609-6e064ea0cf2d/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20191216173652-a0e659d51361/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20191227053925-7b8e75db28f4/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200117161641-43d50277825c/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200122220014-bf1340f18c4a/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200204074204-1cc6d1ef6c74/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200212150539-ea181f53ac56/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200227222343-706bc42d1f0d/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.0.0-20200304193943-95d2e580d8eb/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200312045724-11d5b4c81c7d/go.mod h1:o4KQGtdN14AW+yjsvvwRTJJuXz8XRtIHtEnmAXLyFUw= -golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8= -golang.org/x/tools v0.0.0-20200501065659-ab2804fb9c9d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200512131952-2bc93b1c0c88/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200515010526-7d3b6ebf133d/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200618134242-20370b0cb4b2/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= -golang.org/x/tools v0.0.0-20200729194436-6467de6f59a7/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200804011535-6c149bb5ef0d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc6FUM5FLjQPp3cFF28FI3qnDFljA= -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/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= -google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= -google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.9.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= -google.golang.org/api v0.13.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.14.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.15.0/go.mod h1:iLdEw5Ide6rF15KTC1Kkl0iskquN2gFfn9o9XIsbkAI= -google.golang.org/api v0.17.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.18.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.19.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.20.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.22.0/go.mod h1:BwFmGc8tA3vsd7r/7kR8DY7iEEGSU04BFxCo5jP/sfE= -google.golang.org/api v0.24.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= -google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= -google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= -google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= -google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0= -google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc= -google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190418145605-e7d98fc518a7/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190502173448-54afdca5d873/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= -google.golang.org/genproto v0.0.0-20190801165951-fa694d86fc64/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= -google.golang.org/genproto v0.0.0-20190911173649-1774047e7e51/go.mod h1:IbNlFCBrqXvoKpeg0TB2l7cyZUmoaFKYIwrEpbDKLA8= -google.golang.org/genproto v0.0.0-20191108220845-16a3f7862a1a/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191115194625-c23dd37a84c9/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191216164720-4f79533eabd1/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20191230161307-f3c370f40bfb/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200115191322-ca5a22157cba/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200122232147-0452cf42e150/go.mod h1:n3cpQtvxv34hfy77yVDNjmbRyujviMdxYliBSkLhpCc= -google.golang.org/genproto v0.0.0-20200204135345-fa8e72b47b90/go.mod h1:GmwEX6Z4W5gMy59cAlVYjN9JhxgbQH6Gn+gFDQe2lzA= -google.golang.org/genproto v0.0.0-20200212174721-66ed5ce911ce/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200224152610-e50cd9704f63/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= -google.golang.org/genproto v0.0.0-20200515170657-fc4c6c6a6587/go.mod h1:YsZOwe1myG/8QRHRsmBRE1LrgQY60beZKjly0O1fX9U= -google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= -google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7FcilCzHH/e9qn6dsT145K34l5v+OpcnNgKAAA= -google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= -google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= -google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= -google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= -google.golang.org/grpc v1.26.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.27.1/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= -google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKal+60= -google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= -google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= -google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= -google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= -google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= -google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miEFZTKqfCUM6K7xSMQL9OKL/b6hQv+e19PK+JZNE= -google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= -google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= -google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGjtUeSXeh4= -google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= +google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= +google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQfozc= -gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= +google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= +google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= +gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= 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.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= -honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= -honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= -honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= -rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= -rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= diff --git a/main.go b/main.go index cda44d63..dee1e11d 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,7 @@ package main import ( + "context" "net/http" "os" @@ -9,12 +10,14 @@ import ( "github.com/go-kit/log/level" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" - "github.com/prometheus/common/promlog" - "github.com/prometheus/common/promlog/flag" "github.com/prometheus/common/version" "github.com/prometheus/exporter-toolkit/web" + webflag "github.com/prometheus/exporter-toolkit/web/kingpinflag" _ "github.com/sijms/go-ora/v2" - "gopkg.in/alecthomas/kingpin.v2" + + "github.com/alecthomas/kingpin/v2" + "github.com/prometheus/common/promlog" + "github.com/prometheus/common/promlog/flag" "github.com/observiq/oracledb_exporter/collector" ) @@ -22,47 +25,48 @@ import ( var ( // Version will be set at build time. Version = "0.0.0.dev" - listenAddress = kingpin.Flag("web.listen-address", "Address to listen on for web interface and telemetry. (env: LISTEN_ADDRESS)").Default(getEnv("LISTEN_ADDRESS", ":9161")).String() metricPath = kingpin.Flag("web.telemetry-path", "Path under which to expose metrics. (env: TELEMETRY_PATH)").Default(getEnv("TELEMETRY_PATH", "/metrics")).String() defaultFileMetrics = kingpin.Flag("default.metrics", "File with default metrics in a TOML file. (env: DEFAULT_METRICS)").Default(getEnv("DEFAULT_METRICS", "default-metrics.toml")).String() customMetrics = kingpin.Flag("custom.metrics", "File that may contain various custom metrics in a TOML file. (env: CUSTOM_METRICS)").Default(getEnv("CUSTOM_METRICS", "")).String() queryTimeout = kingpin.Flag("query.timeout", "Query timeout (in seconds). (env: QUERY_TIMEOUT)").Default(getEnv("QUERY_TIMEOUT", "5")).Int() maxIdleConns = kingpin.Flag("database.maxIdleConns", "Number of maximum idle connections in the connection pool. (env: DATABASE_MAXIDLECONNS)").Default(getEnv("DATABASE_MAXIDLECONNS", "0")).Int() maxOpenConns = kingpin.Flag("database.maxOpenConns", "Number of maximum open connections in the connection pool. (env: DATABASE_MAXOPENCONNS)").Default(getEnv("DATABASE_MAXOPENCONNS", "10")).Int() - tlsconfigFile = kingpin.Flag("web.config", "Path to config yaml file that can enable TLS or authentication.").Default("").String() scrapeInterval = kingpin.Flag("scrape.interval", "Interval between each scrape. Default is to scrape on collect requests").Default("0s").Duration() + toolkitFlags = webflag.AddFlags(kingpin.CommandLine, ":9161") ) func main() { promLogConfig := &promlog.Config{} - flag.AddFlags(kingpin.CommandLine, promLogConfig) kingpin.HelpFlag.Short('\n') kingpin.Version(version.Print("oracledb_exporter")) kingpin.Parse() logger := promlog.New(promLogConfig) - dsn := os.Getenv("DATA_SOURCE_NAME") config := &collector.Config{ - DSN: dsn, - MaxOpenConns: *maxOpenConns, - MaxIdleConns: *maxIdleConns, - ScrapeInterval: *scrapeInterval, - CustomMetrics: *customMetrics, - QueryTimeout: *queryTimeout, + DSN: dsn, + MaxOpenConns: *maxOpenConns, + MaxIdleConns: *maxIdleConns, + CustomMetrics: *customMetrics, + QueryTimeout: *queryTimeout, } exporter, err := collector.NewExporter(logger, config) if err != nil { level.Error(logger).Log("unable to connect to DB", err) } + if *scrapeInterval != 0 { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + go exporter.RunScheduledScrapes(ctx, *scrapeInterval) + } + prometheus.MustRegister(exporter) prometheus.MustRegister(version.NewCollector("oracledb_exporter")) level.Info(logger).Log("msg", "Starting oracledb_exporter", "version", version.Info()) level.Info(logger).Log("msg", "Build context", "build", version.BuildContext()) - level.Info(logger).Log("msg", "Starting Server: ", "listen_address", *listenAddress) level.Info(logger).Log("msg", "Collect from: ", "metricPath", *metricPath) opts := promhttp.HandlerOpts{ @@ -73,8 +77,8 @@ func main() { w.Write([]byte("Oracle DB Exporter " + Version + "

Oracle DB Exporter " + Version + "

Metrics

")) }) - server := &http.Server{Addr: *listenAddress} - if err := web.ListenAndServe(server, *tlsconfigFile, logger); err != nil { + server := &http.Server{} + if err := web.ListenAndServe(server, toolkitFlags, logger); err != nil { level.Error(logger).Log("msg", "Listening error", "reason", err) os.Exit(1) } diff --git a/operating-principles.md b/operating-principles.md index 801cba7f..4e69bc98 100644 --- a/operating-principles.md +++ b/operating-principles.md @@ -1,7 +1,7 @@ -Operating principles -==================== +# Operating principles The exporter itself is dumb and does not do much. The initialization is done as follows: + - Parse flags options - Load the default toml file (default-metrics.toml) and store each metrics in a Metric struct - Load the custom toml file (if a custom toml file is given) diff --git a/oraclelinux/Dockerfile b/oraclelinux/Dockerfile index d2ca0ac7..660fb428 100644 --- a/oraclelinux/Dockerfile +++ b/oraclelinux/Dockerfile @@ -1,4 +1,10 @@ -FROM golang:1.19 AS build +# Can't use a variable to refer to external image directly with COPY. +# So using image in a step but doing nothing +ARG ORACLE_IMAGE +FROM ${ORACLE_IMAGE} as oracle-image + +# Build is starting here +FROM docker.io/library/golang:1.19 AS build ARG ORACLE_VERSION ENV ORACLE_VERSION=${ORACLE_VERSION} @@ -6,14 +12,15 @@ ARG MAJOR_VERSION ENV MAJOR_VERSION=${MAJOR_VERSION} ENV LD_LIBRARY_PATH "/usr/lib/oracle/${MAJOR_VERSION}/client64/lib" -RUN apt-get -qq update && apt-get install --no-install-recommends -qq libaio1 rpm -COPY oracle*${ORACLE_VERSION}*.rpm / -RUN rpm -Uh --nodeps /oracle-instantclient*.x86_64.rpm && rm /*.rpm +# Retrieving binaries from oracle image +COPY --from=oracle-image /usr/lib/oracle /usr/lib/oracle +COPY --from=oracle-image /usr/share/oracle /usr/share/oracle +COPY --from=oracle-image /usr/include/oracle /usr/include/oracle COPY oci8.pc.template /usr/share/pkgconfig/oci8.pc RUN sed -i "s/@ORACLE_VERSION@/$ORACLE_VERSION/g" /usr/share/pkgconfig/oci8.pc && \ - sed -i "s/@MAJOR_VERSION@/$MAJOR_VERSION/g" /usr/share/pkgconfig/oci8.pc && \ - find /usr -name oci.pc + sed -i "s/@MAJOR_VERSION@/$MAJOR_VERSION/g" /usr/share/pkgconfig/oci8.pc && \ + find /usr -name oci.pc RUN echo $LD_LIBRARY_PATH >> /etc/ld.so.conf.d/oracle.conf && ldconfig WORKDIR /go/src/oracledb_exporter @@ -24,22 +31,20 @@ ARG VERSION ENV VERSION ${VERSION:-0.1.0} ENV PKG_CONFIG_PATH /go/src/oracledb_exporter -ENV GOOS linux -RUN go build -v -ldflags "-X main.Version=${VERSION} -s -w" +RUN GOOS=linux GOARCH=amd64 go build -v -ldflags "-X main.Version=${VERSION} -s -w" -FROM oraclelinux:8-slim +FROM docker.io/library/oraclelinux:8-slim ARG ORACLE_VERSION ENV ORACLE_VERSION=${ORACLE_VERSION} ARG MAJOR_VERSION ENV MAJOR_VERSION=${MAJOR_VERSION} -RUN microdnf -y install oracle-release-el8 && \ - microdnf -y install oracle-instantclient-release-el8 && \ - microdnf -y install oracle-instantclient-basic && \ - microdnf clean all - +# We only need lib directory +COPY --from=build /usr/lib/oracle /usr/lib/oracle +RUN microdnf -y install libaio && \ + microdnf clean all ARG LEGACY_TABLESPACE ENV LEGACY_TABLESPACE=${LEGACY_TABLESPACE} @@ -47,8 +52,8 @@ COPY --from=build /go/src/oracledb_exporter/oracledb_exporter /oracledb_exporter ADD ./default-metrics${LEGACY_TABLESPACE}.toml /default-metrics.toml RUN chmod 755 /oracledb_exporter && \ - chmod 644 /default-metrics.toml && \ - groupadd www-data && useradd -g www-data www-data + chmod 644 /default-metrics.toml && \ + groupadd www-data && useradd -g www-data www-data USER www-data ENV DATA_SOURCE_NAME system/oracle@oracle/xe ENV LD_LIBRARY_PATH "/usr/lib/oracle/${MAJOR_VERSION}/client64/lib"