- 1.82.1
diff --git a/build/packer/pmm2.el9.json b/build/packer/pmm2.el9.json
index 29d985022b..baa0ef18f2 100644
--- a/build/packer/pmm2.el9.json
+++ b/build/packer/pmm2.el9.json
@@ -26,7 +26,7 @@
],
"region": "us-east-1",
"security_group_id": "sg-688c2b1c",
- "source_ami": "ami-0845395779540e3cb",
+ "source_ami": "ami-0da806cbfc9e67dbb",
"ssh_pty": "true",
"ena_support": "true",
"ssh_username": "ec2-user",
@@ -114,7 +114,8 @@
"inline": [
"sudo yum -y update",
"sudo yum -y install epel-release",
- "sudo yum -y install ansible"
+ "sudo yum -y install ansible-core",
+ "sudo yum -y install ansible-collection-community-general ansible-collection-community-postgresql ansible-collection-ansible-posix"
]
},
{
diff --git a/build/scripts/build-server-rpm b/build/scripts/build-server-rpm
index 09ddbb83c1..0ceccebb23 100755
--- a/build/scripts/build-server-rpm
+++ b/build/scripts/build-server-rpm
@@ -126,7 +126,7 @@ build() {
sleep 1
done
- sudo yum-builddep --randomwait=5 -y SOURCES/${spec_name}.spec
+ sudo yum-builddep --randomwait=1 -y SOURCES/${spec_name}.spec
spectool -C SOURCES -g SOURCES/${spec_name}.spec
rpmbuild --define '_rpmdir %{_topdir}/RPMS/${spec_name}-${rpm_version}' --define 'dist .${rpmbuild_dist}' -ba SOURCES/${spec_name}.spec
diff --git a/build/scripts/build-server-rpm-all b/build/scripts/build-server-rpm-all
index 113937db22..d9cb1a59a2 100755
--- a/build/scripts/build-server-rpm-all
+++ b/build/scripts/build-server-rpm-all
@@ -12,11 +12,13 @@ ${bin_dir}/build-server-rpm pmm-update pmm
${bin_dir}/build-server-rpm dbaas-controller
${bin_dir}/build-server-rpm dbaas-tools
${bin_dir}/build-server-rpm pmm-dump
+${bin_dir}/build-server-rpm grafana-db-migrator
${bin_dir}/build-server-rpm vmproxy pmm
# 3rd-party
${bin_dir}/build-server-rpm victoriametrics
${bin_dir}/build-server-rpm alertmanager
${bin_dir}/build-server-rpm grafana
+# ${bin_dir}/build-server-rpm grafana-db-migrator
# vim: expandtab shiftwidth=4 tabstop=4
diff --git a/build/scripts/create-tags b/build/scripts/create-tags
new file mode 100755
index 0000000000..0f12d9f27c
--- /dev/null
+++ b/build/scripts/create-tags
@@ -0,0 +1,78 @@
+#!/bin/bash
+# Important: This script should never cause the pipeline to fail, so that the tags can be created outside of it.
+# To run it locally, you need pass the version, i.e. export VERSION=2.39.x
+# If run locally, it:
+# - clones pmm-submodules repository and checks out the branch corresponding to the version
+# - skips git ssh configuration and expects the user to set it up ahead of time
+# - uses the current user's creds and email to push tags to the repos, therefore sufficient git permissions are required
+
+set +o errexit
+set +o nounset
+set -o xtrace
+
+# List of repositories whose release branches need to be tagged
+declare repos=(
+ "sources/pmm/src/github.com/percona/pmm"
+ "sources/grafana/src/github.com/grafana/grafana"
+ "sources/grafana-dashboards"
+ "."
+)
+
+# These setting are only needed when running in CI (Jenkins or github actions)
+if [ -n "$CI" ]; then
+ # Configure git settings globally
+ git config --global advice.detachedHead false
+ git config --global user.email "noreply@percona.com"
+ git config --global user.name "PMM Jenkins"
+
+ # Configure git to push using ssh
+ export GIT_SSH_COMMAND="/usr/bin/ssh -i ${SSHKEY} -o StrictHostKeyChecking=no -o LogLevel=error -o UserKnownHostsFile=/dev/null"
+fi
+
+TAG="v${VERSION}"
+echo "We will be tagging repos with a tag: $TAG"
+
+REPO_DIR=pmm-submodules
+if [ -d "$REPO_DIR" ]; then
+ echo "Error: the directory $REPO_DIR already exists, exiting..."
+ exit 0 # this is on purpose, we don't want to fail the pipeline
+fi
+
+if ! git clone --branch "pmm-${VERSION}" --single-branch https://github.com/Percona-Lab/pmm-submodules "$REPO_DIR"; then
+ echo "Fatal: failed to clone pmm-submodules, branch pmm-${VERSION}"
+ exit 0
+fi
+
+cd "$REPO_DIR" >/dev/null
+git submodule update --init
+
+for REPO in "${repos[@]}"; do
+ pushd "$REPO" >/dev/null
+ REPO_URL=$(git config --get remote.origin.url | sed -e "s|^https://github.com/||")
+ git remote set-url origin git@github.com:${REPO_URL}.git
+
+ if git tag -l | grep "$TAG"; then
+ echo "Fatal: tag $TAG already exists in $REPO, exiting..."
+ break
+ fi
+
+ echo "Tagging SHA: $(git rev-parse HEAD)"
+ if [ -n "$CI" ]; then
+ # We can't sign tags in CI, so we create them without signing
+ git tag --message="Version $VERSION." "$TAG"
+ else
+ git tag --message="Version $VERSION." --sign "$TAG"
+ fi
+
+ if ! git push origin "$TAG"; then
+ echo "Fatal: failed to tag the repository $REPO with $TAG, exiting..."
+ popd >/dev/null
+ break
+ fi
+ popd >/dev/null
+done
+
+git submodule status
+cd -
+rm -rf "$REPO_DIR"
+unset repos
diff --git a/build/scripts/create-tags.py b/build/scripts/create-tags.py
deleted file mode 100755
index a8c3a426eb..0000000000
--- a/build/scripts/create-tags.py
+++ /dev/null
@@ -1,48 +0,0 @@
-#!/usr/bin/python2
-
-from __future__ import print_function, unicode_literals
-import os, subprocess, time
-
-REPOS = [
- "sources/pmm/src/github.com/percona/pmm",
- "sources/dbaas-controller/src/github.com/percona-platform/dbaas-controller",
- "sources/pmm-dump",
- "sources/pmm-qa/src/github.com/percona/pmm-qa",
- "sources/pmm-ui-tests/src/github.com/percona/pmm-ui-tests",
- "sources/grafana/src/github.com/grafana/grafana",
- "sources/grafana-dashboards",
- "sources/node_exporter/src/github.com/prometheus/node_exporter",
- "sources/mysqld_exporter/src/github.com/percona/mysqld_exporter",
- "sources/mongodb_exporter/src/github.com/percona/mongodb_exporter",
- "sources/postgres_exporter/src/github.com/percona/postgres_exporter",
- "sources/clickhouse_exporter/src/github.com/Percona-Lab/clickhouse_exporter",
- "sources/proxysql_exporter/src/github.com/percona/proxysql_exporter",
- "sources/rds_exporter/src/github.com/percona/rds_exporter",
- "sources/azure_metrics_exporter/src/github.com/percona/azure_metrics_exporter",
- ".",
-]
-
-tty = subprocess.check_output("tty", shell=True).strip()
-env = os.environ.copy()
-env["GPG_TTY"] = tty
-
-with open("./VERSION", "r") as f:
- version = f.read().strip()
-
-print(tty, version)
-
-subprocess.check_call("git submodule update", shell=True)
-
-for repo in REPOS:
- print("==>", repo)
-
- tag = "v" + version
- cmd = "git tag --message='Version {version}.' --sign {tag}".format(version=version, tag=tag)
- print(">", cmd)
- subprocess.check_call(cmd, shell=True, cwd=repo, env=env)
-
- cmd = "git push origin {tag}".format(tag=tag)
- print(">", cmd)
- subprocess.check_call(cmd, shell=True, cwd=repo)
-
-subprocess.check_call("git submodule status", shell=True)
diff --git a/build/scripts/vars b/build/scripts/vars
index bd267aa95e..789377c71b 100644
--- a/build/scripts/vars
+++ b/build/scripts/vars
@@ -55,5 +55,5 @@ docker_client_tarball=${root_dir}/results/docker/pmm2-client-${pmm_version}.dock
source_tarball=${root_dir}/results/source_tarball/pmm2-client-${pmm_version}.tar.gz
binary_tarball=${root_dir}/results/tarball/pmm2-client-${pmm_version}.tar.gz
-# https://github.com/VictoriaMetrics/VictoriaMetrics/tree/pmm-6401-v1.89.1
-vmagent_commit_hash=88b4c30021ea0785bd052de537252a5cb9a8da3e
+# https://github.com/VictoriaMetrics/VictoriaMetrics/releases/tag/pmm-6401-v1.93.4
+vmagent_commit_hash=58ecb9066574f38f1d1c91ace467316e7f175b09
diff --git a/cli-tests/package-lock.json b/cli-tests/package-lock.json
index 3de0541299..c4dbc70b74 100644
--- a/cli-tests/package-lock.json
+++ b/cli-tests/package-lock.json
@@ -15,18 +15,18 @@
"playwright": "^1.33.0",
"promise-retry": "^2.0.1",
"shelljs": "^0.8.5",
- "typescript": "^5.1.3"
+ "typescript": "^5.2.2"
},
"devDependencies": {
"@types/promise-retry": "^1.1.3",
"@types/shelljs": "^0.8.12",
- "@typescript-eslint/eslint-plugin": "^5.60.1",
- "@typescript-eslint/parser": "^5.60.1",
- "eslint": "8.44",
+ "@typescript-eslint/eslint-plugin": "^6.7.0",
+ "@typescript-eslint/parser": "^6.7.0",
+ "eslint": "8.50",
"eslint-config-airbnb-base": "^15.0.0",
- "eslint-config-airbnb-typescript": "^17.0.0",
- "eslint-plugin-import": "^2.27.5",
- "eslint-plugin-playwright": "^0.15.2"
+ "eslint-config-airbnb-typescript": "^17.1.0",
+ "eslint-plugin-import": "^2.28.0",
+ "eslint-plugin-playwright": "^0.16.0"
}
},
"node_modules/@aashutoshrathi/word-wrap": {
@@ -39,9 +39,9 @@
}
},
"node_modules/@eslint-community/eslint-utils": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.2.0.tgz",
- "integrity": "sha512-gB8T4H4DEfX2IV9zGDJPOBgP1e/DbfCPDTtEqUMckpvzS1OYtva8JdFYBqMwYk7xAQ429WGF/UPqn8uQ//h2vQ==",
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz",
+ "integrity": "sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==",
"dev": true,
"dependencies": {
"eslint-visitor-keys": "^3.3.0"
@@ -54,18 +54,18 @@
}
},
"node_modules/@eslint-community/regexpp": {
- "version": "4.4.0",
- "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.4.0.tgz",
- "integrity": "sha512-A9983Q0LnDGdLPjxyXQ00sbV+K+O+ko2Dr+CZigbHWtX9pNfxlaBkMR8X1CztI73zuEyEBXTVjx7CE+/VSwDiQ==",
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.6.2.tgz",
+ "integrity": "sha512-pPTNuaAG3QMH+buKyBIGJs3g/S5y0caxw0ygM3YyE6yJFySwiGGSzA+mM3KJ8QQvzeLh3blwgSonkFjgQdxzMw==",
"dev": true,
"engines": {
"node": "^12.0.0 || ^14.0.0 || >=16.0.0"
}
},
"node_modules/@eslint/eslintrc": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.0.tgz",
- "integrity": "sha512-Lj7DECXqIVCqnqjjHMPna4vn6GJcMgul/wuS0je9OZ9gsL0zzDpKPVtcG1HaDVc+9y+qgXneTeUMbCqXJNpH1A==",
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.2.tgz",
+ "integrity": "sha512-+wvgpDsrB1YqAMdEUCcnTlpfVBH7Vqn6A/NT3D8WVXFIaKMlErPIZT3oCIAVCOtarRpMtelZLqJeU3t7WY6X6g==",
"dev": true,
"dependencies": {
"ajv": "^6.12.4",
@@ -86,18 +86,18 @@
}
},
"node_modules/@eslint/js": {
- "version": "8.44.0",
- "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.44.0.tgz",
- "integrity": "sha512-Ag+9YM4ocKQx9AarydN0KY2j0ErMHNIocPDrVo8zAE44xLTjEtz81OdR68/cydGtk6m6jDb5Za3r2useMzYmSw==",
+ "version": "8.50.0",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.50.0.tgz",
+ "integrity": "sha512-NCC3zz2+nvYd+Ckfh87rA47zfu2QsQpvc6k1yzTk+b9KzRj0wkGa8LSoGOXN6Zv4lRf/EIoZ80biDh9HOI+RNQ==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
}
},
"node_modules/@humanwhocodes/config-array": {
- "version": "0.11.10",
- "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.10.tgz",
- "integrity": "sha512-KVVjQmNUepDVGXNuoRRdmmEjruj0KfiGSbS8LVc12LMsWDQzRXJ0qdhN8L8uUigKpfEHRhlaQFY0ib1tnUbNeQ==",
+ "version": "0.11.11",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.11.11.tgz",
+ "integrity": "sha512-N2brEuAadi0CcdeMXUkhbZB84eskAc8MEX1By6qEchoVywSgXPIjou4rYsl0V3Hj0ZnuGycGCjdNgockbzeWNA==",
"dev": true,
"dependencies": {
"@humanwhocodes/object-schema": "^1.2.1",
@@ -245,9 +245,9 @@
"dev": true
},
"node_modules/@types/semver": {
- "version": "7.5.0",
- "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.0.tgz",
- "integrity": "sha512-G8hZ6XJiHnuhQKR7ZmysCeJWE08o8T0AXtk5darsCaTVsYZhhgUrq53jizaR2FvsoeCwJhlmwTjkXBY5Pn/ZHw==",
+ "version": "7.5.1",
+ "resolved": "https://registry.npmjs.org/@types/semver/-/semver-7.5.1.tgz",
+ "integrity": "sha512-cJRQXpObxfNKkFAZbJl2yjWtJCqELQIdShsogr1d2MilP8dKD9TE/nEKHkJgUNHdGKCQaf9HbIynuV2csLGVLg==",
"dev": true
},
"node_modules/@types/shelljs": {
@@ -261,32 +261,33 @@
}
},
"node_modules/@typescript-eslint/eslint-plugin": {
- "version": "5.60.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-5.60.1.tgz",
- "integrity": "sha512-KSWsVvsJsLJv3c4e73y/Bzt7OpqMCADUO846bHcuWYSYM19bldbAeDv7dYyV0jwkbMfJ2XdlzwjhXtuD7OY6bw==",
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.7.0.tgz",
+ "integrity": "sha512-gUqtknHm0TDs1LhY12K2NA3Rmlmp88jK9Tx8vGZMfHeNMLE3GH2e9TRub+y+SOjuYgtOmok+wt1AyDPZqxbNag==",
"dev": true,
"dependencies": {
- "@eslint-community/regexpp": "^4.4.0",
- "@typescript-eslint/scope-manager": "5.60.1",
- "@typescript-eslint/type-utils": "5.60.1",
- "@typescript-eslint/utils": "5.60.1",
+ "@eslint-community/regexpp": "^4.5.1",
+ "@typescript-eslint/scope-manager": "6.7.0",
+ "@typescript-eslint/type-utils": "6.7.0",
+ "@typescript-eslint/utils": "6.7.0",
+ "@typescript-eslint/visitor-keys": "6.7.0",
"debug": "^4.3.4",
- "grapheme-splitter": "^1.0.4",
- "ignore": "^5.2.0",
- "natural-compare-lite": "^1.4.0",
- "semver": "^7.3.7",
- "tsutils": "^3.21.0"
+ "graphemer": "^1.4.0",
+ "ignore": "^5.2.4",
+ "natural-compare": "^1.4.0",
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "@typescript-eslint/parser": "^5.0.0",
- "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "@typescript-eslint/parser": "^6.0.0 || ^6.0.0-alpha",
+ "eslint": "^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -295,25 +296,26 @@
}
},
"node_modules/@typescript-eslint/parser": {
- "version": "5.60.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-5.60.1.tgz",
- "integrity": "sha512-pHWlc3alg2oSMGwsU/Is8hbm3XFbcrb6P5wIxcQW9NsYBfnrubl/GhVVD/Jm/t8HXhA2WncoIRfBtnCgRGV96Q==",
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-6.7.0.tgz",
+ "integrity": "sha512-jZKYwqNpNm5kzPVP5z1JXAuxjtl2uG+5NpaMocFPTNC2EdYIgbXIPImObOkhbONxtFTTdoZstLZefbaK+wXZng==",
"dev": true,
"dependencies": {
- "@typescript-eslint/scope-manager": "5.60.1",
- "@typescript-eslint/types": "5.60.1",
- "@typescript-eslint/typescript-estree": "5.60.1",
+ "@typescript-eslint/scope-manager": "6.7.0",
+ "@typescript-eslint/types": "6.7.0",
+ "@typescript-eslint/typescript-estree": "6.7.0",
+ "@typescript-eslint/visitor-keys": "6.7.0",
"debug": "^4.3.4"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "eslint": "^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -322,16 +324,16 @@
}
},
"node_modules/@typescript-eslint/scope-manager": {
- "version": "5.60.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-5.60.1.tgz",
- "integrity": "sha512-Dn/LnN7fEoRD+KspEOV0xDMynEmR3iSHdgNsarlXNLGGtcUok8L4N71dxUgt3YvlO8si7E+BJ5Fe3wb5yUw7DQ==",
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-6.7.0.tgz",
+ "integrity": "sha512-lAT1Uau20lQyjoLUQ5FUMSX/dS07qux9rYd5FGzKz/Kf8W8ccuvMyldb8hadHdK/qOI7aikvQWqulnEq2nCEYA==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.60.1",
- "@typescript-eslint/visitor-keys": "5.60.1"
+ "@typescript-eslint/types": "6.7.0",
+ "@typescript-eslint/visitor-keys": "6.7.0"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
@@ -339,25 +341,25 @@
}
},
"node_modules/@typescript-eslint/type-utils": {
- "version": "5.60.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.60.1.tgz",
- "integrity": "sha512-vN6UztYqIu05nu7JqwQGzQKUJctzs3/Hg7E2Yx8rz9J+4LgtIDFWjjl1gm3pycH0P3mHAcEUBd23LVgfrsTR8A==",
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-6.7.0.tgz",
+ "integrity": "sha512-f/QabJgDAlpSz3qduCyQT0Fw7hHpmhOzY/Rv6zO3yO+HVIdPfIWhrQoAyG+uZVtWAIS85zAyzgAFfyEr+MgBpg==",
"dev": true,
"dependencies": {
- "@typescript-eslint/typescript-estree": "5.60.1",
- "@typescript-eslint/utils": "5.60.1",
+ "@typescript-eslint/typescript-estree": "6.7.0",
+ "@typescript-eslint/utils": "6.7.0",
"debug": "^4.3.4",
- "tsutils": "^3.21.0"
+ "ts-api-utils": "^1.0.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "*"
+ "eslint": "^7.0.0 || ^8.0.0"
},
"peerDependenciesMeta": {
"typescript": {
@@ -366,12 +368,12 @@
}
},
"node_modules/@typescript-eslint/types": {
- "version": "5.60.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.60.1.tgz",
- "integrity": "sha512-zDcDx5fccU8BA0IDZc71bAtYIcG9PowaOwaD8rjYbqwK7dpe/UMQl3inJ4UtUK42nOCT41jTSCwg76E62JpMcg==",
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-6.7.0.tgz",
+ "integrity": "sha512-ihPfvOp7pOcN/ysoj0RpBPOx3HQTJTrIN8UZK+WFd3/iDeFHHqeyYxa4hQk4rMhsz9H9mXpR61IzwlBVGXtl9Q==",
"dev": true,
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
@@ -379,21 +381,21 @@
}
},
"node_modules/@typescript-eslint/typescript-estree": {
- "version": "5.60.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.60.1.tgz",
- "integrity": "sha512-hkX70J9+2M2ZT6fhti5Q2FoU9zb+GeZK2SLP1WZlvUDqdMbEKhexZODD1WodNRyO8eS+4nScvT0dts8IdaBzfw==",
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-6.7.0.tgz",
+ "integrity": "sha512-dPvkXj3n6e9yd/0LfojNU8VMUGHWiLuBZvbM6V6QYD+2qxqInE7J+J/ieY2iGwR9ivf/R/haWGkIj04WVUeiSQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.60.1",
- "@typescript-eslint/visitor-keys": "5.60.1",
+ "@typescript-eslint/types": "6.7.0",
+ "@typescript-eslint/visitor-keys": "6.7.0",
"debug": "^4.3.4",
"globby": "^11.1.0",
"is-glob": "^4.0.3",
- "semver": "^7.3.7",
- "tsutils": "^3.21.0"
+ "semver": "^7.5.4",
+ "ts-api-utils": "^1.0.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
@@ -406,42 +408,41 @@
}
},
"node_modules/@typescript-eslint/utils": {
- "version": "5.60.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.60.1.tgz",
- "integrity": "sha512-tiJ7FFdFQOWssFa3gqb94Ilexyw0JVxj6vBzaSpfN/8IhoKkDuSAenUKvsSHw2A/TMpJb26izIszTXaqygkvpQ==",
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-6.7.0.tgz",
+ "integrity": "sha512-MfCq3cM0vh2slSikQYqK2Gq52gvOhe57vD2RM3V4gQRZYX4rDPnKLu5p6cm89+LJiGlwEXU8hkYxhqqEC/V3qA==",
"dev": true,
"dependencies": {
- "@eslint-community/eslint-utils": "^4.2.0",
- "@types/json-schema": "^7.0.9",
- "@types/semver": "^7.3.12",
- "@typescript-eslint/scope-manager": "5.60.1",
- "@typescript-eslint/types": "5.60.1",
- "@typescript-eslint/typescript-estree": "5.60.1",
- "eslint-scope": "^5.1.1",
- "semver": "^7.3.7"
+ "@eslint-community/eslint-utils": "^4.4.0",
+ "@types/json-schema": "^7.0.12",
+ "@types/semver": "^7.5.0",
+ "@typescript-eslint/scope-manager": "6.7.0",
+ "@typescript-eslint/types": "6.7.0",
+ "@typescript-eslint/typescript-estree": "6.7.0",
+ "semver": "^7.5.4"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/typescript-eslint"
},
"peerDependencies": {
- "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ "eslint": "^7.0.0 || ^8.0.0"
}
},
"node_modules/@typescript-eslint/visitor-keys": {
- "version": "5.60.1",
- "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-5.60.1.tgz",
- "integrity": "sha512-xEYIxKcultP6E/RMKqube11pGjXH1DCo60mQoWhVYyKfLkwbIVVjYxmOenNMxILx0TjCujPTjjnTIVzm09TXIw==",
+ "version": "6.7.0",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-6.7.0.tgz",
+ "integrity": "sha512-/C1RVgKFDmGMcVGeD8HjKv2bd72oI1KxQDeY8uc66gw9R0OK0eMq48cA+jv9/2Ag6cdrsUGySm1yzYmfz0hxwQ==",
"dev": true,
"dependencies": {
- "@typescript-eslint/types": "5.60.1",
- "eslint-visitor-keys": "^3.3.0"
+ "@typescript-eslint/types": "6.7.0",
+ "eslint-visitor-keys": "^3.4.1"
},
"engines": {
- "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ "node": "^16.0.0 || >=18.0.0"
},
"funding": {
"type": "opencollective",
@@ -449,9 +450,9 @@
}
},
"node_modules/acorn": {
- "version": "8.9.0",
- "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.9.0.tgz",
- "integrity": "sha512-jaVNAFBHNLXspO543WnNNPZFRtavh3skAkITqD0/2aeMkKZTN+254PyhwxFYrk3vQ1xfY+2wbesJMs/JC8/PwQ==",
+ "version": "8.10.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.10.0.tgz",
+ "integrity": "sha512-F0SAmZ8iUtS//m8DmCTA0jlh6TDKkHQyK6xc6V4KDTyZKA9dnvX9/3sRTVQrWm79glUAZbnmmNcdYwUIHWVybw==",
"dev": true,
"bin": {
"acorn": "bin/acorn"
@@ -515,6 +516,19 @@
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
"dev": true
},
+ "node_modules/array-buffer-byte-length": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz",
+ "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "is-array-buffer": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/array-includes": {
"version": "3.1.6",
"resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.6.tgz",
@@ -543,6 +557,25 @@
"node": ">=8"
}
},
+ "node_modules/array.prototype.findlastindex": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.2.tgz",
+ "integrity": "sha512-tb5thFFlUcp7NdNF6/MpDk/1r/4awWG1FIz3YqDf+/zJSTezBb+/5WViH41obXULHVpDzoiCLpJ/ZO9YbJMsdw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4",
+ "es-shim-unscopables": "^1.0.0",
+ "get-intrinsic": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/array.prototype.flat": {
"version": "1.3.1",
"resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.1.tgz",
@@ -579,6 +612,38 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/arraybuffer.prototype.slice": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.1.tgz",
+ "integrity": "sha512-09x0ZWFEjj4WD8PDbykUwo3t9arLn8NIzmmYEJFpYekOAQjpkGSyrQhNoRTcwwcFRu+ycWF78QZ63oWTqSjBcw==",
+ "dev": true,
+ "dependencies": {
+ "array-buffer-byte-length": "^1.0.0",
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "get-intrinsic": "^1.2.1",
+ "is-array-buffer": "^3.0.2",
+ "is-shared-array-buffer": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/available-typed-arrays": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz",
+ "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@@ -710,9 +775,9 @@
"dev": true
},
"node_modules/define-properties": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.4.tgz",
- "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.0.tgz",
+ "integrity": "sha512-xvqAVKGfT1+UAvPwKTVw/njhdQ8ZhXK4lI0bCIuCMrp2up9nPnaDftrLtmpTazqd1o+UY4zgzU+avtMbDP+ldA==",
"dev": true,
"dependencies": {
"has-property-descriptors": "^1.0.0",
@@ -766,35 +831,50 @@
"integrity": "sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA=="
},
"node_modules/es-abstract": {
- "version": "1.20.4",
- "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.20.4.tgz",
- "integrity": "sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==",
+ "version": "1.22.1",
+ "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.1.tgz",
+ "integrity": "sha512-ioRRcXMO6OFyRpyzV3kE1IIBd4WG5/kltnzdxSCqoP8CMGs/Li+M1uF5o7lOkZVFjDs+NLesthnF66Pg/0q0Lw==",
"dev": true,
"dependencies": {
+ "array-buffer-byte-length": "^1.0.0",
+ "arraybuffer.prototype.slice": "^1.0.1",
+ "available-typed-arrays": "^1.0.5",
"call-bind": "^1.0.2",
+ "es-set-tostringtag": "^2.0.1",
"es-to-primitive": "^1.2.1",
- "function-bind": "^1.1.1",
"function.prototype.name": "^1.1.5",
- "get-intrinsic": "^1.1.3",
+ "get-intrinsic": "^1.2.1",
"get-symbol-description": "^1.0.0",
+ "globalthis": "^1.0.3",
+ "gopd": "^1.0.1",
"has": "^1.0.3",
"has-property-descriptors": "^1.0.0",
+ "has-proto": "^1.0.1",
"has-symbols": "^1.0.3",
- "internal-slot": "^1.0.3",
+ "internal-slot": "^1.0.5",
+ "is-array-buffer": "^3.0.2",
"is-callable": "^1.2.7",
"is-negative-zero": "^2.0.2",
"is-regex": "^1.1.4",
"is-shared-array-buffer": "^1.0.2",
"is-string": "^1.0.7",
+ "is-typed-array": "^1.1.10",
"is-weakref": "^1.0.2",
- "object-inspect": "^1.12.2",
+ "object-inspect": "^1.12.3",
"object-keys": "^1.1.1",
"object.assign": "^4.1.4",
- "regexp.prototype.flags": "^1.4.3",
+ "regexp.prototype.flags": "^1.5.0",
+ "safe-array-concat": "^1.0.0",
"safe-regex-test": "^1.0.0",
- "string.prototype.trimend": "^1.0.5",
- "string.prototype.trimstart": "^1.0.5",
- "unbox-primitive": "^1.0.2"
+ "string.prototype.trim": "^1.2.7",
+ "string.prototype.trimend": "^1.0.6",
+ "string.prototype.trimstart": "^1.0.6",
+ "typed-array-buffer": "^1.0.0",
+ "typed-array-byte-length": "^1.0.0",
+ "typed-array-byte-offset": "^1.0.0",
+ "typed-array-length": "^1.0.4",
+ "unbox-primitive": "^1.0.2",
+ "which-typed-array": "^1.1.10"
},
"engines": {
"node": ">= 0.4"
@@ -803,6 +883,20 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/es-set-tostringtag": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.1.tgz",
+ "integrity": "sha512-g3OMbtlwY3QewlqAiMLI47KywjWZoEytKr8pf6iTC8uJq5bIAH52Z9pnQ8pVL6whrCto53JZDuUIsifGeLorTg==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.3",
+ "has": "^1.0.3",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
"node_modules/es-shim-unscopables": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.0.tgz",
@@ -842,27 +936,27 @@
}
},
"node_modules/eslint": {
- "version": "8.44.0",
- "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.44.0.tgz",
- "integrity": "sha512-0wpHoUbDUHgNCyvFB5aXLiQVfK9B0at6gUvzy83k4kAsQ/u769TQDX6iKC+aO4upIHO9WSaA3QoXYQDHbNwf1A==",
+ "version": "8.50.0",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.50.0.tgz",
+ "integrity": "sha512-FOnOGSuFuFLv/Sa+FDVRZl4GGVAAFFi8LecRsI5a1tMO5HIE8nCm4ivAlzt4dT3ol/PaaGC0rJEEXQmHJBGoOg==",
"dev": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
- "@eslint-community/regexpp": "^4.4.0",
- "@eslint/eslintrc": "^2.1.0",
- "@eslint/js": "8.44.0",
- "@humanwhocodes/config-array": "^0.11.10",
+ "@eslint-community/regexpp": "^4.6.1",
+ "@eslint/eslintrc": "^2.1.2",
+ "@eslint/js": "8.50.0",
+ "@humanwhocodes/config-array": "^0.11.11",
"@humanwhocodes/module-importer": "^1.0.1",
"@nodelib/fs.walk": "^1.2.8",
- "ajv": "^6.10.0",
+ "ajv": "^6.12.4",
"chalk": "^4.0.0",
"cross-spawn": "^7.0.2",
"debug": "^4.3.2",
"doctrine": "^3.0.0",
"escape-string-regexp": "^4.0.0",
- "eslint-scope": "^7.2.0",
- "eslint-visitor-keys": "^3.4.1",
- "espree": "^9.6.0",
+ "eslint-scope": "^7.2.2",
+ "eslint-visitor-keys": "^3.4.3",
+ "espree": "^9.6.1",
"esquery": "^1.4.2",
"esutils": "^2.0.2",
"fast-deep-equal": "^3.1.3",
@@ -872,7 +966,6 @@
"globals": "^13.19.0",
"graphemer": "^1.4.0",
"ignore": "^5.2.0",
- "import-fresh": "^3.0.0",
"imurmurhash": "^0.1.4",
"is-glob": "^4.0.0",
"is-path-inside": "^3.0.3",
@@ -884,7 +977,6 @@
"natural-compare": "^1.4.0",
"optionator": "^0.9.3",
"strip-ansi": "^6.0.1",
- "strip-json-comments": "^3.1.0",
"text-table": "^0.2.0"
},
"bin": {
@@ -926,16 +1018,16 @@
}
},
"node_modules/eslint-config-airbnb-typescript": {
- "version": "17.0.0",
- "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.0.0.tgz",
- "integrity": "sha512-elNiuzD0kPAPTXjFWg+lE24nMdHMtuxgYoD30OyMD6yrW1AhFZPAg27VX7d3tzOErw+dgJTNWfRSDqEcXb4V0g==",
+ "version": "17.1.0",
+ "resolved": "https://registry.npmjs.org/eslint-config-airbnb-typescript/-/eslint-config-airbnb-typescript-17.1.0.tgz",
+ "integrity": "sha512-GPxI5URre6dDpJ0CtcthSZVBAfI+Uw7un5OYNVxP2EYi3H81Jw701yFP7AU+/vCE7xBtFmjge7kfhhk4+RAiig==",
"dev": true,
"dependencies": {
"eslint-config-airbnb-base": "^15.0.0"
},
"peerDependencies": {
- "@typescript-eslint/eslint-plugin": "^5.13.0",
- "@typescript-eslint/parser": "^5.0.0",
+ "@typescript-eslint/eslint-plugin": "^5.13.0 || ^6.0.0",
+ "@typescript-eslint/parser": "^5.0.0 || ^6.0.0",
"eslint": "^7.32.0 || ^8.2.0",
"eslint-plugin-import": "^2.25.3"
}
@@ -961,9 +1053,9 @@
}
},
"node_modules/eslint-module-utils": {
- "version": "2.7.4",
- "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.7.4.tgz",
- "integrity": "sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==",
+ "version": "2.8.0",
+ "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz",
+ "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==",
"dev": true,
"dependencies": {
"debug": "^3.2.7"
@@ -987,26 +1079,29 @@
}
},
"node_modules/eslint-plugin-import": {
- "version": "2.27.5",
- "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.27.5.tgz",
- "integrity": "sha512-LmEt3GVofgiGuiE+ORpnvP+kAm3h6MLZJ4Q5HCyHADofsb4VzXFsRiWj3c0OFiV+3DWFh0qg3v9gcPlfc3zRow==",
+ "version": "2.28.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.28.0.tgz",
+ "integrity": "sha512-B8s/n+ZluN7sxj9eUf7/pRFERX0r5bnFA2dCaLHy2ZeaQEAz0k+ZZkFWRFHJAqxfxQDx6KLv9LeIki7cFdwW+Q==",
"dev": true,
"dependencies": {
"array-includes": "^3.1.6",
+ "array.prototype.findlastindex": "^1.2.2",
"array.prototype.flat": "^1.3.1",
"array.prototype.flatmap": "^1.3.1",
"debug": "^3.2.7",
"doctrine": "^2.1.0",
"eslint-import-resolver-node": "^0.3.7",
- "eslint-module-utils": "^2.7.4",
+ "eslint-module-utils": "^2.8.0",
"has": "^1.0.3",
- "is-core-module": "^2.11.0",
+ "is-core-module": "^2.12.1",
"is-glob": "^4.0.3",
"minimatch": "^3.1.2",
+ "object.fromentries": "^2.0.6",
+ "object.groupby": "^1.0.0",
"object.values": "^1.1.6",
- "resolve": "^1.22.1",
- "semver": "^6.3.0",
- "tsconfig-paths": "^3.14.1"
+ "resolve": "^1.22.3",
+ "semver": "^6.3.1",
+ "tsconfig-paths": "^3.14.2"
},
"engines": {
"node": ">=4"
@@ -1037,18 +1132,18 @@
}
},
"node_modules/eslint-plugin-import/node_modules/semver": {
- "version": "6.3.0",
- "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz",
- "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==",
+ "version": "6.3.1",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz",
+ "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==",
"dev": true,
"bin": {
"semver": "bin/semver.js"
}
},
"node_modules/eslint-plugin-playwright": {
- "version": "0.15.2",
- "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-0.15.2.tgz",
- "integrity": "sha512-Q2jQ7ORjZscvwxR6MEgITZy23vxlnYlJlMR7aICFczWVMijTCZPGvvMoZaLWkAzx5J6fciulwbg+JJeRjMkTig==",
+ "version": "0.16.0",
+ "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-0.16.0.tgz",
+ "integrity": "sha512-DcHpF0SLbNeh9MT4pMzUGuUSnJ7q5MWbP8sSEFIMS6j7Ggnduq8ghNlfhURgty4c1YFny7Ge9xYTO1FSAoV2Vw==",
"dev": true,
"peerDependencies": {
"eslint": ">=7",
@@ -1060,23 +1155,10 @@
}
}
},
- "node_modules/eslint-scope": {
- "version": "5.1.1",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
- "integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
- "dev": true,
- "dependencies": {
- "esrecurse": "^4.3.0",
- "estraverse": "^4.1.1"
- },
- "engines": {
- "node": ">=8.0.0"
- }
- },
"node_modules/eslint-visitor-keys": {
- "version": "3.4.1",
- "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.1.tgz",
- "integrity": "sha512-pZnmmLwYzf+kWaM/Qgrvpen51upAktaaiI01nsJD/Yr3lMOdNtq0cxkrrg16w64VtisN6okbs7Q8AfGqj4c9fA==",
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
"dev": true,
"engines": {
"node": "^12.22.0 || ^14.17.0 || >=16.0.0"
@@ -1086,9 +1168,9 @@
}
},
"node_modules/eslint/node_modules/eslint-scope": {
- "version": "7.2.0",
- "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.0.tgz",
- "integrity": "sha512-DYj5deGlHBfMt15J7rdtyKNq/Nqlv5KfU4iodrQ019XESsRnwXH9KAE0y3cwtUHDo2ob7CypAnCqefh6vioWRw==",
+ "version": "7.2.2",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz",
+ "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==",
"dev": true,
"dependencies": {
"esrecurse": "^4.3.0",
@@ -1111,9 +1193,9 @@
}
},
"node_modules/espree": {
- "version": "9.6.0",
- "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.0.tgz",
- "integrity": "sha512-1FH/IiruXZ84tpUlm0aCUEwMl2Ho5ilqVh0VvQXw+byAz/4SAciyHLlfmL5WYqsvD38oymdUwBss0LtK8m4s/A==",
+ "version": "9.6.1",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz",
+ "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==",
"dev": true,
"dependencies": {
"acorn": "^8.9.0",
@@ -1169,15 +1251,6 @@
"node": ">=4.0"
}
},
- "node_modules/estraverse": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
- "integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
- "dev": true,
- "engines": {
- "node": ">=4.0"
- }
- },
"node_modules/esutils": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
@@ -1301,6 +1374,15 @@
"integrity": "sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==",
"dev": true
},
+ "node_modules/for-each": {
+ "version": "0.3.3",
+ "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz",
+ "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==",
+ "dev": true,
+ "dependencies": {
+ "is-callable": "^1.1.3"
+ }
+ },
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@@ -1352,13 +1434,14 @@
}
},
"node_modules/get-intrinsic": {
- "version": "1.1.3",
- "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.1.3.tgz",
- "integrity": "sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==",
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz",
+ "integrity": "sha512-2DcsyfABl+gVHEfCOaTrWgyt+tb6MSEGmKq+kI5HwLbIYgjgmMcV8KQ41uaKz1xxUcn9tJtgFbQUEVcEbd0FYw==",
"dev": true,
"dependencies": {
"function-bind": "^1.1.1",
"has": "^1.0.3",
+ "has-proto": "^1.0.1",
"has-symbols": "^1.0.3"
},
"funding": {
@@ -1413,9 +1496,9 @@
}
},
"node_modules/globals": {
- "version": "13.20.0",
- "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz",
- "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==",
+ "version": "13.21.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz",
+ "integrity": "sha512-ybyme3s4yy/t/3s35bewwXKOf7cvzfreG2lH0lZl0JB7I4GxRP2ghxOK/Nb9EkRXdbBXZLfq/p/0W2JUONB/Gg==",
"dev": true,
"dependencies": {
"type-fest": "^0.20.2"
@@ -1427,6 +1510,21 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/globalthis": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz",
+ "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==",
+ "dev": true,
+ "dependencies": {
+ "define-properties": "^1.1.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/globby": {
"version": "11.1.0",
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
@@ -1447,11 +1545,17 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
- "node_modules/grapheme-splitter": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz",
- "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==",
- "dev": true
+ "node_modules/gopd": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz",
+ "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==",
+ "dev": true,
+ "dependencies": {
+ "get-intrinsic": "^1.1.3"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
},
"node_modules/graphemer": {
"version": "1.4.0",
@@ -1500,6 +1604,18 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/has-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz",
+ "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==",
+ "dev": true,
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/has-symbols": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz",
@@ -1528,9 +1644,9 @@
}
},
"node_modules/ignore": {
- "version": "5.2.0",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.0.tgz",
- "integrity": "sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==",
+ "version": "5.2.4",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.2.4.tgz",
+ "integrity": "sha512-MAb38BcSbH0eHNBxn7ql2NH/kX33OkB3lZ1BNdh7ENeRChHTYsTvWrMubiIAMNS2llXEEgZ1MUOBtXChP3kaFQ==",
"dev": true,
"engines": {
"node": ">= 4"
@@ -1576,12 +1692,12 @@
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
},
"node_modules/internal-slot": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.3.tgz",
- "integrity": "sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==",
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.5.tgz",
+ "integrity": "sha512-Y+R5hJrzs52QCG2laLn4udYVnxsfny9CpOhNhUvk/SSSVyF6T27FzRbF0sroPidSu3X8oEAkOn2K804mjpt6UQ==",
"dev": true,
"dependencies": {
- "get-intrinsic": "^1.1.0",
+ "get-intrinsic": "^1.2.0",
"has": "^1.0.3",
"side-channel": "^1.0.4"
},
@@ -1597,6 +1713,20 @@
"node": ">= 0.10"
}
},
+ "node_modules/is-array-buffer": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz",
+ "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.0",
+ "is-typed-array": "^1.1.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/is-bigint": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz",
@@ -1638,9 +1768,9 @@
}
},
"node_modules/is-core-module": {
- "version": "2.11.0",
- "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz",
- "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==",
+ "version": "2.12.1",
+ "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.12.1.tgz",
+ "integrity": "sha512-Q4ZuBAe2FUsKtyQJoQHlvP8OvBERxO3jEmy1I7hcRXcJBGGHFh/aJBswbXuS9sgrDH2QUO8ilkwNPHvHMd8clg==",
"dependencies": {
"has": "^1.0.3"
},
@@ -1787,6 +1917,21 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/is-typed-array": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz",
+ "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==",
+ "dev": true,
+ "dependencies": {
+ "which-typed-array": "^1.1.11"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/is-weakref": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz",
@@ -1799,6 +1944,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/isarray": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz",
+ "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==",
+ "dev": true
+ },
"node_modules/isexe": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
@@ -1929,9 +2080,9 @@
}
},
"node_modules/minimist": {
- "version": "1.2.7",
- "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz",
- "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==",
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -1949,16 +2100,10 @@
"integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
"dev": true
},
- "node_modules/natural-compare-lite": {
- "version": "1.4.0",
- "resolved": "https://registry.npmjs.org/natural-compare-lite/-/natural-compare-lite-1.4.0.tgz",
- "integrity": "sha512-Tj+HTDSJJKaZnfiuw+iaF9skdPpTo2GtEly5JHnWV/hfv2Qj/9RKsGISQtLh2ox3l5EAGw487hnBee0sIJ6v2g==",
- "dev": true
- },
"node_modules/object-inspect": {
- "version": "1.12.2",
- "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.2.tgz",
- "integrity": "sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==",
+ "version": "1.12.3",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz",
+ "integrity": "sha512-geUvdk7c+eizMNUDkRpW1wJwgfOiOeHbxBR/hLXK1aT6zmVSO0jsQcs7fj6MGw89jC/cjGfLcNOrtMYtGqm81g==",
"dev": true,
"funding": {
"url": "https://github.com/sponsors/ljharb"
@@ -2005,6 +2150,35 @@
"node": ">= 0.4"
}
},
+ "node_modules/object.fromentries": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.6.tgz",
+ "integrity": "sha512-VciD13dswC4j1Xt5394WR4MzmAQmlgN72phd/riNp9vtD7tp4QQWJ0R4wvclXcafgcYK8veHRed2W6XeGBvcfg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/object.groupby": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.0.tgz",
+ "integrity": "sha512-70MWG6NfRH9GnbZOikuhPPYzpUpof9iW2J9E4dW7FXTqPNb6rllE6u39SKwwiNh8lCwX3DDb5OgcKGiEBrTTyw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.2.0",
+ "es-abstract": "^1.21.2",
+ "get-intrinsic": "^1.2.1"
+ }
+ },
"node_modules/object.values": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.6.tgz",
@@ -2229,14 +2403,14 @@
}
},
"node_modules/regexp.prototype.flags": {
- "version": "1.4.3",
- "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.4.3.tgz",
- "integrity": "sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==",
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.0.tgz",
+ "integrity": "sha512-0SutC3pNudRKgquxGoRGIz946MZVHqbNfPjBdxeOhBrdgDKlRoXmYLQN9xRbrR09ZXWeGAdPuif7egofn6v5LA==",
"dev": true,
"dependencies": {
"call-bind": "^1.0.2",
- "define-properties": "^1.1.3",
- "functions-have-names": "^1.2.2"
+ "define-properties": "^1.2.0",
+ "functions-have-names": "^1.2.3"
},
"engines": {
"node": ">= 0.4"
@@ -2246,11 +2420,11 @@
}
},
"node_modules/resolve": {
- "version": "1.22.1",
- "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz",
- "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "version": "1.22.3",
+ "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.3.tgz",
+ "integrity": "sha512-P8ur/gp/AmbEzjr729bZnLjXK5Z+4P0zhIJgBgzqRih7hL7BOukHGtSTA3ACMY467GRFz3duQsi0bDZdR7DKdw==",
"dependencies": {
- "is-core-module": "^2.9.0",
+ "is-core-module": "^2.12.0",
"path-parse": "^1.0.7",
"supports-preserve-symlinks-flag": "^1.0.0"
},
@@ -2326,6 +2500,24 @@
"queue-microtask": "^1.2.2"
}
},
+ "node_modules/safe-array-concat": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.0.0.tgz",
+ "integrity": "sha512-9dVEFruWIsnie89yym+xWTAYASdpw3CJV7Li/6zBewGf9z2i1j31rP6jnY0pHEO4QZh6N0K11bFjWmdR8UGdPQ==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.0",
+ "has-symbols": "^1.0.3",
+ "isarray": "^2.0.5"
+ },
+ "engines": {
+ "node": ">=0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/safe-regex-test": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.0.tgz",
@@ -2341,9 +2533,9 @@
}
},
"node_modules/semver": {
- "version": "7.3.8",
- "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz",
- "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==",
+ "version": "7.5.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz",
+ "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==",
"dev": true,
"dependencies": {
"lru-cache": "^6.0.0"
@@ -2415,6 +2607,23 @@
"node": ">=8"
}
},
+ "node_modules/string.prototype.trim": {
+ "version": "1.2.7",
+ "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.7.tgz",
+ "integrity": "sha512-p6TmeT1T3411M8Cgg9wBTMRtY2q9+PNy9EV1i2lIXUN/btt763oIfxwN3RR8VU6wHX8j/1CFy0L+YuThm6bgOg==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "define-properties": "^1.1.4",
+ "es-abstract": "^1.20.4"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/string.prototype.trimend": {
"version": "1.0.6",
"resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.6.tgz",
@@ -2517,39 +2726,30 @@
"node": ">=8.0"
}
},
+ "node_modules/ts-api-utils": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-1.0.1.tgz",
+ "integrity": "sha512-lC/RGlPmwdrIBFTX59wwNzqh7aR2otPNPR/5brHZm/XKFYKsfqxihXUe9pU3JI+3vGkl+vyCoNNnPhJn3aLK1A==",
+ "dev": true,
+ "engines": {
+ "node": ">=16.13.0"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.2.0"
+ }
+ },
"node_modules/tsconfig-paths": {
- "version": "3.14.1",
- "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.1.tgz",
- "integrity": "sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==",
+ "version": "3.14.2",
+ "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.14.2.tgz",
+ "integrity": "sha512-o/9iXgCYc5L/JxCHPe3Hvh8Q/2xm5Z+p18PESBU6Ff33695QnCHBEjcytY2q19ua7Mbl/DavtBOLq+oG0RCL+g==",
"dev": true,
"dependencies": {
"@types/json5": "^0.0.29",
- "json5": "^1.0.1",
+ "json5": "^1.0.2",
"minimist": "^1.2.6",
"strip-bom": "^3.0.0"
}
},
- "node_modules/tslib": {
- "version": "1.14.1",
- "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz",
- "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==",
- "dev": true
- },
- "node_modules/tsutils": {
- "version": "3.21.0",
- "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz",
- "integrity": "sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==",
- "dev": true,
- "dependencies": {
- "tslib": "^1.8.1"
- },
- "engines": {
- "node": ">= 6"
- },
- "peerDependencies": {
- "typescript": ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta"
- }
- },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -2574,10 +2774,75 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
+ "node_modules/typed-array-buffer": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz",
+ "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "get-intrinsic": "^1.2.1",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/typed-array-byte-length": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz",
+ "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "has-proto": "^1.0.1",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-byte-offset": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz",
+ "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==",
+ "dev": true,
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "has-proto": "^1.0.1",
+ "is-typed-array": "^1.1.10"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/typed-array-length": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz",
+ "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==",
+ "dev": true,
+ "dependencies": {
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "is-typed-array": "^1.1.9"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/typescript": {
- "version": "5.1.3",
- "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.1.3.tgz",
- "integrity": "sha512-XH627E9vkeqhlZFQuL+UsyAXEnibT0kWR2FWONlr4sTjvxyJYnyefgrkyECLzM5NenmKzRAy2rR/OlYLA1HkZw==",
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.2.2.tgz",
+ "integrity": "sha512-mI4WrpHsbCIcwT9cF4FZvr80QUeKvsUsUvKDoR+X/7XHQH98xYD8YHZg7ANtz2GtZt/CBq2QJ0thkGJMHfqc1w==",
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@@ -2641,6 +2906,25 @@
"url": "https://github.com/sponsors/ljharb"
}
},
+ "node_modules/which-typed-array": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.11.tgz",
+ "integrity": "sha512-qe9UWWpkeG5yzZ0tNYxDmd7vo58HDBc39mZ0xWWpolAGADdFOzkfamWLDxkOWcvHQKVmdTyQdLD4NOfjLWTKew==",
+ "dev": true,
+ "dependencies": {
+ "available-typed-arrays": "^1.0.5",
+ "call-bind": "^1.0.2",
+ "for-each": "^0.3.3",
+ "gopd": "^1.0.1",
+ "has-tostringtag": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
"node_modules/wrappy": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
diff --git a/cli-tests/package.json b/cli-tests/package.json
index 94e07b67a8..f6fe7cd1aa 100644
--- a/cli-tests/package.json
+++ b/cli-tests/package.json
@@ -19,17 +19,17 @@
"playwright": "^1.33.0",
"promise-retry": "^2.0.1",
"shelljs": "^0.8.5",
- "typescript": "^5.1.3"
+ "typescript": "^5.2.2"
},
"devDependencies": {
"@types/promise-retry": "^1.1.3",
"@types/shelljs": "^0.8.12",
- "@typescript-eslint/eslint-plugin": "^5.60.1",
- "@typescript-eslint/parser": "^5.60.1",
- "eslint": "8.44",
+ "@typescript-eslint/eslint-plugin": "^6.7.0",
+ "@typescript-eslint/parser": "^6.7.0",
+ "eslint": "8.50",
"eslint-config-airbnb-base": "^15.0.0",
- "eslint-config-airbnb-typescript": "^17.0.0",
- "eslint-plugin-import": "^2.27.5",
- "eslint-plugin-playwright": "^0.15.2"
+ "eslint-config-airbnb-typescript": "^17.1.0",
+ "eslint-plugin-import": "^2.28.0",
+ "eslint-plugin-playwright": "^0.16.0"
}
}
diff --git a/dev/mongo-rs-backups/docker-compose.yml b/dev/mongo-rs-backups/docker-compose.yml
index 458674b664..001be6355c 100644
--- a/dev/mongo-rs-backups/docker-compose.yml
+++ b/dev/mongo-rs-backups/docker-compose.yml
@@ -1,6 +1,7 @@
networks:
pmm_default:
name: pmm_default
+ external: true
services:
mongo1:
diff --git a/devcontainer.Dockerfile b/devcontainer.Dockerfile
index 8c0addb822..0f12d4180a 100644
--- a/devcontainer.Dockerfile
+++ b/devcontainer.Dockerfile
@@ -2,11 +2,11 @@ ARG PMM_SERVER_IMAGE="perconalab/pmm-server:dev-latest"
FROM $PMM_SERVER_IMAGE
ARG PMM_SERVER_IMAGE
-ARG GO_VERSION="1.20.x"
+ARG GO_VERSION="1.21.x"
-RUN echo "Building with: GO: ${GO_VERSION}, PMM: ${PMM_SERVER_IMAGE}" && \
- export GOPATH=$(go env GOPATH) && \
- export PATH="${GOPATH}/bin:${PATH}"
+RUN echo "Building with: GO: $GO_VERSION, PMM: $PMM_SERVER_IMAGE"
+ENV GOPATH=/root/go
+ENV PATH="$PATH:$GOPATH/bin"
RUN mkdir -p $GOPATH/src/github.com/percona/pmm
WORKDIR $GOPATH/src/github.com/percona/pmm
diff --git a/docker-compose.yml b/docker-compose.yml
index d516be2235..566c7495d8 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -100,20 +100,45 @@ services:
# /opt/entrypoint.sh
# "
- # PMM with external ClickHouse DB
+ # PMM with external DBs
ch:
profiles:
- - pmm-ch
+ - pmm-external-dbs
image: ${CH_IMAGE:-clickhouse/clickhouse-server:22.6.9.11-alpine}
platform: linux/amd64
hostname: ${CH_HOSTNAME:-ch}
ports:
- ${CH_PORT:-9000}:9000
- pmm-server-ch:
+ networks:
+ - ${NETWORK:-default}
+ victoriametrics:
+ profiles:
+ - pmm-external-dbs
+ hostname: ${VM_HOSTNAME:-victoriametrics}
+ image: victoriametrics/victoria-metrics:v1.88.1
+ ports:
+ - 8428:8428
+ - 8089:8089
+ - 8089:8089/udp
+ - 2003:2003
+ - 2003:2003/udp
+ - 4242:4242
+ volumes:
+ - vmdata:/storage
+ command:
+ - "--storageDataPath=/storage"
+ - "--graphiteListenAddr=:2003"
+ - "--opentsdbListenAddr=:4242"
+ - "--httpListenAddr=:8428"
+ - "--influxListenAddr=:8089"
+ networks:
+ - ${NETWORK:-default}
+ pmm-managed-server-ch:
profiles:
- - pmm-ch
+ - pmm-external-dbs
depends_on:
- ch
+ - victoriametrics
image: ${PMM_CONTAINER:-perconalab/pmm-server:dev-container}
container_name: pmm-server
hostname: pmm-server
@@ -136,7 +161,8 @@ services:
- PERCONA_TEST_PMM_CLICKHOUSE_DATABASE=pmm
- PERCONA_TEST_PMM_CLICKHOUSE_BLOCK_SIZE=10000
- PERCONA_TEST_PMM_CLICKHOUSE_POOL_SIZE=2
- # - PMM_DEBUG=1
+ - PMM_VM_URL=${PMM_VM_URL:-http://victoriametrics:8428/}
+ - PMM_DEBUG=1
- PERCONA_TEST_DBAAS_PMM_CLIENT=perconalab/pmm-client:dev-latest
extra_hosts:
@@ -161,13 +187,6 @@ services:
- ${PMM_PORT_HTTPS:-443}:443
# For headless delve
- ${PMM_PORT_DELVE:-2345}:2345
- # PG
- - ${PMM_PORT_PG:-15432}:5432
- # VM
- - ${PMM_PORT_VM:-9090}:9090
- # CH
- - ${PMM_PORT_CH_TCP:-11000}:9000
- - ${PMM_PORT_CH_HTTP:-11123}:8123
volumes:
- ./:/root/go/src/github.com/percona/pmm
# - "../grafana/public:/usr/share/grafana/public"
@@ -207,4 +226,5 @@ services:
volumes:
go-modules:
+ vmdata: {}
root-cache:
diff --git a/docs/api/addnode.md b/docs/api/addnode.md
new file mode 100644
index 0000000000..2b177c72bf
--- /dev/null
+++ b/docs/api/addnode.md
@@ -0,0 +1,69 @@
+---
+slug: 'addnode'
+---
+
+## Add a Node
+
+This section describes how to add a Node of any type to the inventory.
+
+In PMM versions prior to 2.40.0, we featured a separate API call for each Node type. Starting with PMM 2.40.0, we have a single API call for all Node types. The API call is `Add` and the Node type is specified in the `node_type` field. The `node_type` field is required. Along with this single API endpoint, we are deprecating the separate API calls for each Node type.
+
+Let's see how to add a Node of type `GENERIC_NODE` using the old and new API calls.
+
+Old API call:
+
+````bash:
+
+```bash
+curl --insecure -X POST \
+ -H 'Authorization: Basic YWRtaW46YWRtaW4=' \
+ -H 'Accept: application/json' \
+ -H 'Content-Type: application/json' \
+ --url https://127.0.0.1/v1/inventory/Nodes/AddGeneric \
+ --data '
+{
+ "node_name": "mysql-sales-db-prod-1",
+ "region": "us-east-1",
+ "az": "us-east-1a",
+ "address": "209.0.25.100",
+ "custom_labels": {
+ "environment": "sales-prod",
+ "department": "sales"
+ }
+}
+'
+````
+
+New API call:
+
+```bash
+curl --insecure -X POST \
+ -H 'Authorization: Basic YWRtaW46YWRtaW4=' \
+ -H 'Accept: application/json' \
+ -H 'Content-Type: application/json' \
+ --url https://127.0.0.1/v1/inventory/Nodes/Add \
+ --data '
+{
+ "generic": {
+ "node_name": "mysql-sales-db-prod-1",
+ "region": "us-east-1",
+ "az": "us-east-1a",
+ "address": "209.0.25.100",
+ "custom_labels": {
+ "environment": "sales-prod",
+ "department": "sales"
+ }
+ }
+}
+'
+```
+
+To get the authentication token, please visit [this page](ref:authentication).
+
+You can choose from the following Node types:
+
+- GENERIC_NODE: `generic`
+- CONTAINER_NODE: `container`
+- REMOTE_NODE: `remote`
+- REMOTE_RDS_NODE: `remote_rds`
+- REMOTE_AZURE_DATABASE_NODE: `remote_azure`
diff --git a/docs/api/adhoc-backup.md b/docs/api/adhoc-backup.md
index 4988cf9c3a..fcd94af324 100644
--- a/docs/api/adhoc-backup.md
+++ b/docs/api/adhoc-backup.md
@@ -4,16 +4,14 @@ slug: 'adhoc-backup'
## Ad hoc Backup
-PMM can backup the monitored servers.
+PMM can backup the monitored servers.
This section describes making ad hoc backups from a service.
-
### Creating a Backup
Here is an example of a Curl API call to create a backup:
-
```bash
curl --insecure -X POST -H 'Authorization: Bearer XXXXX' \
--request POST \
@@ -32,9 +30,8 @@ curl --insecure -X POST -H 'Authorization: Bearer XXXXX' \
'
```
-You require an authentication string which is described [here](ref:authentication).
+You require an authentication token, which is described [here](ref:authentication).
Also, you require the [service_id](ref:listservices) and [location_id](ref:listlocations).
-You can choose a `name` and `description` for the backup. You can also configure `retry_interval` and `retries` if required.
-
+You can choose a `name` and `description` for the backup. You can also configure `retry_interval` and `retries` if required.
diff --git a/docs/api/authentication.md b/docs/api/authentication.md
index 4e04f11d1a..2379589217 100644
--- a/docs/api/authentication.md
+++ b/docs/api/authentication.md
@@ -23,7 +23,7 @@ Let's assume the username is `admin` and the password is also `admin`. Then the
```bash
curl -X GET -H 'Authorization: Basic YWRtaW46YWRtaW4=' \
- -H 'Content-Type: application/json' https://127.0.0.1/v1/version
+ -H 'Content-Type: application/json' https://127.0.0.1/v1/version
```
If you use `curl` to make API calls, a simple equivalent to the command above is:
@@ -34,19 +34,18 @@ curl -X GET -u admin:admin -H 'Content-Type: application/json' https://127.0.0.1
### Bearer Authentication
-Bearer authentication (also called token authentication) is an HTTP authentication scheme that involves security tokens called bearer tokens. The bearer token is a cryptic API key, which can be generated by the server admin from the Settings UI or via a respective API call (read more about how to generate an API key). The client must send the API key in the `Authorization` header when making requests to protected resources:
+Bearer authentication (also called token authentication) is an HTTP authentication scheme that involves security tokens called bearer tokens. The bearer token is a cryptic API key, which can be generated by the server admin from the Settings UI or via a respective API call (read more about how to generate an API key). The client must send the API key in the `Authorization` header when making requests to protected resources:
```bash
curl -X GET -H 'Authorization: Bearer eyJrIjoiUXRkeDNMS1g1bFVyY0tUj1o0SmhBc3g4QUdTRVAwekoiLCJuIjoicG1tLXRlc3QiLCJpZCI6MX0=' \
- -H 'Content-Type: application/json' https://127.0.0.1/v1/version
+ -H 'Content-Type: application/json' https://127.0.0.1/v1/version
```
You can use the API key in basic authentication as well:
```bash
curl -X GET -H 'Content-Type: application/json' \
-https://api_key:eyJrIjoiUXRkeDNMS1g1bFVyY0tUj1o0SmhBc3g4QUdTRVAwekoiLCJuIjoicG1tLXRlc3QiLCJpZCI6MX0=@127.0.0.1/v1/version
-
+ https://api_key:eyJrIjoiUXRkeDNMS1g1bFVyY0tUj1o0SmhBc3g4QUdTRVAwekoiLCJuIjoicG1tLXRlc3QiLCJpZCI6MX0=@127.0.0.1/v1/version
```
### Protecting Credentials
@@ -58,11 +57,13 @@ In the previous examples, the credentials can be gleaned from the shell history
It is possible to hide from the shell history:
bash
+
```bash
set +o history
```
zsh
+
```zsh
SAVEHIST=0
```
@@ -78,16 +79,19 @@ password admin
```
This can then be used as follows:
+
```bash
curl --netrc -X GET -H 'Content-Type: application/json' https://127.0.0.1/v1/version
```
Should you wish to use a different file then the `--netrc-file` option needs to be used. If we have the credentials stored in `~/.netrc-pmm` then the command would become:
+
```bash
curl --netrc --netrc-file ~/.netrc-pmm -X GET -H 'Content-Type: application/json' https://127.0.0.1/v1/version
```
You can use API keys in this way too, for example:
+
```
machine 127.0.0.1
login api_key
diff --git a/docs/api/listlocations.md b/docs/api/listlocations.md
index 0053a47bcf..63d0187575 100644
--- a/docs/api/listlocations.md
+++ b/docs/api/listlocations.md
@@ -4,14 +4,14 @@ slug: 'listlocations'
## List Locations
-The following Curl API call will list all the available Locations:
+The following API call will list all the available Locations:
```bash
-curl --insecure -X POST -H 'Authorization: Bearer XXXXX' \
- --request POST \
- --url https://127.0.0.1/v1/management/backup/Locations/List \
- --header 'Accept: application/json' \
- --header 'Content-Type: application/json'
+curl --insecure -X POST \
+ -H 'Authorization: Basic YWRtaW46YWRtaW4=' \
+ -H 'Accept: application/json' \
+ -H 'Content-Type: application/json' \
+ --url https://127.0.0.1/v1/management/backup/Locations/List \
```
-You will need the [authetication string](ref:authentication).
\ No newline at end of file
+You will need the [authetication token](ref:authentication).
diff --git a/docs/api/listnodes.md b/docs/api/listnodes.md
index 6a45b229cb..ba5740e3e5 100644
--- a/docs/api/listnodes.md
+++ b/docs/api/listnodes.md
@@ -4,26 +4,25 @@ slug: 'listnodes'
## List Nodes
-This section describes listing the Nodes in the inventory.
+This section describes how to list PMM Inventory Nodes.
Example:
+
```bash
-curl --insecure -X POST -H 'Authorization: Bearer XXXXX'
- --request POST
- --url https://127.0.0.1/v1/inventory/Nodes/List
- --header 'Accept: application/json'
- --header 'Content-Type: application/json'
- --data '
-{
- "node_type": "GENERIC_NODE"
-}
-'
+curl --insecure -X POST \
+ -H 'Authorization: Basic YWRtaW46YWRtaW4=' \
+ -H 'Accept: application/json' \
+ -H 'Content-Type: application/json' \
+ --url https://127.0.0.1/v1/inventory/Nodes/List \
+ --data '{"node_type": "GENERIC_NODE"}'
```
-Firstly, get the [authentication string](ref:authentication).
-
-Then, choose from the following Node types:
-`NODE_TYPE_INVALID, GENERIC_NODE, CONTAINER_NODE, REMOTE_NODE, REMOTE_RDS_NODE, REMOTE_AZURE_DATABASE_NODE`
-
+First, get the [authentication token](ref:authentication).
+Then, choose from the following Node types:
+- GENERIC_NODE
+- CONTAINER_NODE
+- REMOTE_NODE
+- REMOTE_RDS_NODE
+- REMOTE_AZURE_DATABASE_NODE`
diff --git a/docs/api/listservices.md b/docs/api/listservices.md
index b95bed1f1f..51d79dcb19 100644
--- a/docs/api/listservices.md
+++ b/docs/api/listservices.md
@@ -7,25 +7,31 @@ slug: 'listservices'
The following API call lists the available services on a Node:
```bash
-curl --insecure -X POST -H 'Authorization: Bearer XXXXX' \
- --request POST \
- --url https://127.0.0.1/v1/inventory/Services/List \
- --header 'Accept: application/json' \
- --header 'Content-Type: application/json' \
- --data '
+curl --insecure -X POST \
+ -H 'Authorization: Basic YWRtaW46YWRtaW4=' \
+ -H 'Accept: application/json' \
+ -H 'Content-Type: application/json' \
+ --url https://127.0.0.1/v1/inventory/Services/List \
+ --data '
{
"node_id": "/node_id/XXXXX",
"service_type": "MYSQL_SERVICE"
}'
```
-Firstly, get the [authentication string](ref:authentication).
+First, get the [authentication token](ref:authentication).
-Then, you require the [node_id](ref:listnodes).
+Then, you need to know the [node_id](ref:listnodes).
Choose the `service_type` that you want to list. The options are:
-`SERVICE_TYPE_INVALID, MYSQL_SERVICE, MONGODB_SERVICE, POSTGRESQL_SERVICE, PROXYSQL_SERVICE, HAPROXY_SERVICE, EXTERNAL_SERVICE`
+
+- MYSQL_SERVICE
+- MONGODB_SERVICE
+- POSTGRESQL_SERVICE
+- PROXYSQL_SERVICE
+- HAPROXY_SERVICE
+- EXTERNAL_SERVICE
If you prefer to get all services running on the node, you can omit the `service_type` parameter.
-However, calling the same endpoint without any parameters will return all services known to this PMM instance.
+Otherwise, calling the same endpoint with no parameters will return all services known to this PMM instance.
diff --git a/docs/process/tech_stack.md b/docs/process/tech_stack.md
index 1785731eba..a5778b127d 100644
--- a/docs/process/tech_stack.md
+++ b/docs/process/tech_stack.md
@@ -10,14 +10,14 @@ Currently, our development team has fewer people than components/repositories. I
- [protobuf v3](https://developers.google.com/protocol-buffers/) gives us [strongly-typed](https://developers.google.com/protocol-buffers/docs/proto3) serialization format with good [forward- and backward-compatibility](https://developers.google.com/protocol-buffers/docs/gotutorial#extending-a-protocol-buffer), [canonical mapping to and from JSON](https://developers.google.com/protocol-buffers/docs/proto3#json), and a large ecosystem of libraries and tools. We don't have to write code to work with it because there are code generators for a lot of languages.
- [gRPC](https://grpc.io/) extends protobuf with RPC mechanism. Both single requests/responses and bi-directional streams are supported. Error handling is built-in. Again, there are code generators for both client- and server-side code, so we don't have to write it by ourselves.
-- [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) takes gRPC specification and generates code for HTTP JSON API server-side wrapper for it. It also generates [Swagger](https://swagger.io/) specification from protocol specification and annotations, with documentation from comments. In turn, it is used to generate client-side code for environments where gRPC is not yet supported natively (e.g. web browser). No manual writing of serialization and communication code, and documentation with examples and interactive tools – gRPC specification becomes the single source of truth.
+- [grpc-gateway](https://github.com/grpc-ecosystem/grpc-gateway) takes gRPC specification and generates code for HTTP JSON API server-side wrapper for it. It also generates [Swagger](https://swagger.io/) specification from protocol specification and annotations, with documentation built up from comments. In turn, it is used to generate client-side code for environments where gRPC is not yet supported natively (e.g. web browser). No manual writing of serialization and communication code, and documentation with examples and interactive tools – gRPC specification becomes the single source of truth.
- [logrus](https://github.com/sirupsen/logrus) or stdlib `log` package should be used for logging. Always log to unbuffered stderr, let process supervisor do the rest.
- [prometheus client](https://github.com/prometheus/client_golang) is used for exposing internal metrics of application and gRPC library.
- [testify](https://github.com/stretchr/testify) or stdlib `testing` package should be used for writing tests. Testify should be used only for `assert` and `require` packages – suites here have some problems with logging and parallel tests. Common setups and teardowns should be implemented with `testing` [subtests](https://golang.org/pkg/testing/#hdr-Subtests_and_Sub_benchmarks).
- [golangci-lint](https://github.com/golangci/golangci-lint) is used for static code checks.
- [gocov.io](http://gocov.io/) and [gocoverutil](https://github.com/AlekSi/gocoverutil) gather code coverage metrics.
- [Docker Compose](https://docs.docker.com/compose/) is used for a local development environment and in CI.
-- [Kong](https://github.com/alecthomas/kong) for pmm CLI and [kingpin.v2](http://gopkg.in/alecthomas/kingpin.v2) for exporters and some other code. Use [Kong](https://github.com/alecthomas/kong) if you need some new CLI or need to make significant changes to the old `kingpin.v2` CLI.
+- [Kong](https://github.com/alecthomas/kong) for PMM CLI and [kingpin.v2](http://gopkg.in/alecthomas/kingpin.v2) for exporters and some other code. Use [Kong](https://github.com/alecthomas/kong) if you want to contribute a brand new CLI or need to make significant changes to the old `kingpin.v2`-based CLI.
- [go modules](https://go.dev/ref/mod#introduction) for vendoring.
## Open questions
diff --git a/go.mod b/go.mod
index 228d77be02..a04583a6a7 100644
--- a/go.mod
+++ b/go.mod
@@ -1,6 +1,6 @@
module github.com/percona/pmm
-go 1.20
+go 1.21
// Update saas with
// go get -v github.com/percona-platform/saas@latest
@@ -18,22 +18,22 @@ replace github.com/ClickHouse/clickhouse-go/151 => github.com/ClickHouse/clickho
require (
github.com/AlekSi/pointer v1.2.0
github.com/ClickHouse/clickhouse-go/151 v0.0.0-00010101000000-000000000000
- github.com/ClickHouse/clickhouse-go/v2 v2.10.0
+ github.com/ClickHouse/clickhouse-go/v2 v2.13.0
github.com/DATA-DOG/go-sqlmock v1.5.0
github.com/alecthomas/kong v0.8.0
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137
- github.com/aws/aws-sdk-go v1.44.273
+ github.com/aws/aws-sdk-go v1.45.2
github.com/blang/semver v3.5.1+incompatible
- github.com/brianvoe/gofakeit/v6 v6.22.0
- github.com/charmbracelet/bubbles v0.15.0
- github.com/charmbracelet/bubbletea v0.24.0
- github.com/charmbracelet/lipgloss v0.7.1
+ github.com/brianvoe/gofakeit/v6 v6.23.0
+ github.com/charmbracelet/bubbles v0.16.1
+ github.com/charmbracelet/bubbletea v0.24.1
+ github.com/charmbracelet/lipgloss v0.8.0
github.com/davecgh/go-spew v1.1.1
github.com/docker/docker v23.0.4+incompatible
github.com/docker/go-connections v0.4.0
- github.com/envoyproxy/protoc-gen-validate v1.0.1
- github.com/go-co-op/gocron v1.30.0
- github.com/go-openapi/errors v0.20.3
+ github.com/envoyproxy/protoc-gen-validate v1.0.2
+ github.com/go-co-op/gocron v1.31.0
+ github.com/go-openapi/errors v0.20.4
github.com/go-openapi/runtime v0.26.0
github.com/go-openapi/strfmt v0.21.7
github.com/go-openapi/swag v0.22.3
@@ -42,10 +42,10 @@ require (
github.com/golang-migrate/migrate/v4 v4.16.1
github.com/golang/protobuf v1.5.3
github.com/google/uuid v1.3.0
- github.com/grafana/grafana-api-golang-client v0.23.0
+ github.com/grafana/grafana-api-golang-client v0.24.0
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0
- github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0
github.com/hashicorp/go-version v1.6.0
github.com/jmoiron/sqlx v1.3.5
github.com/jotaen/kong-completion v0.0.5
@@ -54,7 +54,7 @@ require (
github.com/operator-framework/api v0.17.6
github.com/operator-framework/operator-lifecycle-manager v0.24.0
github.com/percona-platform/dbaas-api v0.0.0-20230103182808-d79c449a9f4c
- github.com/percona-platform/saas v0.0.0-20230306173543-c223f9a47342
+ github.com/percona-platform/saas v0.0.0-20230728161159-ad6bdeb8a3d9
github.com/percona/dbaas-operator v0.1.6
github.com/percona/exporter_shared v0.7.4
github.com/percona/go-mysql v0.0.0-20210427141028-73d29c6da78c
@@ -71,26 +71,26 @@ require (
github.com/stretchr/objx v0.5.0
github.com/stretchr/testify v1.8.4
go.mongodb.org/mongo-driver v1.12.0
- go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd
- golang.org/x/crypto v0.10.0
+ go.starlark.net v0.0.0-20230717150657-8a3343210976
+ golang.org/x/crypto v0.13.0
golang.org/x/sync v0.3.0
- golang.org/x/sys v0.9.0
- golang.org/x/text v0.10.0
- golang.org/x/tools v0.10.0
- google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc
- google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc
- google.golang.org/grpc v1.57.0-dev
+ golang.org/x/sys v0.12.0
+ golang.org/x/text v0.13.0
+ golang.org/x/tools v0.13.0
+ google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d
+ google.golang.org/grpc v1.58.0
google.golang.org/protobuf v1.31.0
gopkg.in/alecthomas/kingpin.v2 v2.2.6
gopkg.in/reform.v1 v1.5.1
gopkg.in/yaml.v3 v3.0.1
- k8s.io/api v0.27.2
+ k8s.io/api v0.28.0
k8s.io/apiextensions-apiserver v0.26.2
- k8s.io/apimachinery v0.27.2
- k8s.io/cli-runtime v0.27.2
- k8s.io/client-go v0.27.2
- k8s.io/kubectl v0.27.2
- modernc.org/sqlite v1.23.0
+ k8s.io/apimachinery v0.28.0
+ k8s.io/cli-runtime v0.28.0
+ k8s.io/client-go v0.28.0
+ k8s.io/kubectl v0.28.0
+ modernc.org/sqlite v1.25.0
sigs.k8s.io/controller-runtime v0.14.6
)
@@ -105,10 +105,10 @@ require (
github.com/evanphx/json-patch/v5 v5.6.0 // indirect
github.com/go-errors/errors v1.4.2 // indirect
github.com/go-ini/ini v1.67.0 // indirect
- github.com/go-logr/logr v1.2.3 // indirect
+ github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
- github.com/google/gnostic v0.6.9 // indirect
+ github.com/google/gnostic-models v0.6.8 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 // indirect
@@ -127,28 +127,29 @@ require (
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab // indirect
github.com/sergi/go-diff v1.2.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
- github.com/xlab/treeprint v1.1.0 // indirect
- go.uber.org/atomic v1.10.0 // indirect
+ github.com/xlab/treeprint v1.2.0 // indirect
+ go.opentelemetry.io/otel/metric v1.16.0 // indirect
+ go.uber.org/atomic v1.11.0 // indirect
golang.org/x/exp v0.0.0-20230522175609-2e198f4a06a1 // indirect
golang.org/x/time v0.3.0 // indirect
- google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e // indirect
+ google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 // indirect
gopkg.in/inf.v0 v0.9.1 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
- k8s.io/klog/v2 v2.90.1 // indirect
- k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f // indirect
- k8s.io/utils v0.0.0-20230209194617-a36077c30491 // indirect
+ k8s.io/klog/v2 v2.100.1 // indirect
+ k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 // indirect
+ k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 // indirect
lukechampine.com/uint128 v1.2.0 // indirect
modernc.org/cc/v3 v3.40.0 // indirect
modernc.org/ccgo/v3 v3.16.13 // indirect
- modernc.org/libc v1.22.5 // indirect
+ modernc.org/libc v1.24.1 // indirect
modernc.org/mathutil v1.5.0 // indirect
- modernc.org/memory v1.5.0 // indirect
+ modernc.org/memory v1.6.0 // indirect
modernc.org/opt v0.1.3 // indirect
modernc.org/strutil v1.1.3 // indirect
modernc.org/token v1.0.1 // indirect
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd // indirect
- sigs.k8s.io/kustomize/api v0.13.2 // indirect
- sigs.k8s.io/kustomize/kyaml v0.14.1 // indirect
+ sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 // indirect
+ sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 // indirect
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 // indirect
sigs.k8s.io/yaml v1.3.0 // indirect
)
@@ -177,7 +178,7 @@ require (
github.com/go-faster/errors v0.6.1 // indirect
github.com/go-openapi/analysis v0.21.4 // indirect
github.com/go-openapi/jsonpointer v0.19.6 // indirect
- github.com/go-openapi/jsonreference v0.20.1 // indirect
+ github.com/go-openapi/jsonreference v0.20.2 // indirect
github.com/go-openapi/loads v0.21.2 // indirect
github.com/go-openapi/spec v0.20.8 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
@@ -207,12 +208,12 @@ require (
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b // indirect
github.com/muesli/cancelreader v0.2.2 // indirect
github.com/muesli/reflow v0.3.0 // indirect
- github.com/muesli/termenv v0.15.1 // indirect
+ github.com/muesli/termenv v0.15.2 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.3-0.20211202183452-c5a74bcca799 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
- github.com/paulmach/orb v0.9.0 // indirect
+ github.com/paulmach/orb v0.10.0 // indirect
github.com/pierrec/lz4/v4 v4.1.17 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/prometheus/client_model v0.4.0 // indirect
@@ -225,12 +226,12 @@ require (
github.com/xdg-go/scram v1.1.2 // indirect
github.com/xdg-go/stringprep v1.0.4 // indirect
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a // indirect
- go.opentelemetry.io/otel v1.14.0 // indirect
- go.opentelemetry.io/otel/trace v1.14.0 // indirect
- golang.org/x/mod v0.11.0 // indirect
- golang.org/x/net v0.11.0 // indirect
- golang.org/x/oauth2 v0.8.0 // indirect
- golang.org/x/term v0.9.0 // indirect
+ go.opentelemetry.io/otel v1.16.0 // indirect
+ go.opentelemetry.io/otel/trace v1.16.0 // indirect
+ golang.org/x/mod v0.12.0 // indirect
+ golang.org/x/net v0.15.0 // indirect
+ golang.org/x/oauth2 v0.12.0 // indirect
+ golang.org/x/term v0.12.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gotest.tools/v3 v3.3.0 // indirect
diff --git a/go.sum b/go.sum
index 3eff9f9962..6403803950 100644
--- a/go.sum
+++ b/go.sum
@@ -49,12 +49,14 @@ github.com/Azure/azure-storage-blob-go v0.13.0/go.mod h1:pA9kNqtjUeQF2zOSu4s//nU
github.com/Azure/azure-storage-blob-go v0.14.0 h1:1BCg74AmVdYwO3dlKwtFU1V0wU2PZdREkXvAmZJRUlM=
github.com/Azure/azure-storage-blob-go v0.14.0/go.mod h1:SMqIBi+SuiQH32bvyjngEewEeXoPfKMgWlBDaYf6fck=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
+github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
github.com/Azure/go-autorest/autorest v0.11.28 h1:ndAExarwr5Y+GaHE6VCaY1kyS/HwwGGyuimVhWsHOEM=
github.com/Azure/go-autorest/autorest/adal v0.9.2/go.mod h1:/3SMAM86bP6wC9Ev35peQDUeqFZBMH07vvUOmg4z/fE=
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
github.com/Azure/go-autorest/autorest/adal v0.9.21 h1:jjQnVFXPfekaqb8vIsv2G1lxshoW+oGv4MDlhRtnYZk=
+github.com/Azure/go-autorest/autorest/adal v0.9.21/go.mod h1:zua7mBUaCc5YnSLKYgGJR/w5ePdMDA6H56upLsHzA9U=
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
@@ -72,8 +74,8 @@ github.com/ClickHouse/clickhouse-go v1.5.1 h1:I8zVFZTz80crCs0FFEBJooIxsPcV0xfthz
github.com/ClickHouse/clickhouse-go v1.5.1/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
github.com/ClickHouse/clickhouse-go v1.5.4 h1:cKjXeYLNWVJIx2J1K6H2CqyRmfwVJVY1OV1coaaFcI0=
github.com/ClickHouse/clickhouse-go v1.5.4/go.mod h1:EaI/sW7Azgz9UATzd5ZdZHRUhHgv5+JMS9NSr2smCJI=
-github.com/ClickHouse/clickhouse-go/v2 v2.10.0 h1:0w/A50D5MfsRUYBaV6rLKwZ4LXWKLZKJ1u31QXjTIO4=
-github.com/ClickHouse/clickhouse-go/v2 v2.10.0/go.mod h1:teXfZNM90iQ99Jnuht+dxQXCuhDZ8nvvMoTJOFrcmcg=
+github.com/ClickHouse/clickhouse-go/v2 v2.13.0 h1:oP1OlTQIbQKKLnqLzyDhiyNFvN3pbOtM+e/3qdexG9k=
+github.com/ClickHouse/clickhouse-go/v2 v2.13.0/go.mod h1:xyL0De2K54/n+HGsdtPuyYJq76wefafaHfGUXTDEq/0=
github.com/DATA-DOG/go-sqlmock v1.5.0 h1:Shsta01QNfFxHCfpW6YH2STWB0MudeXXEWMr20OEh60=
github.com/DATA-DOG/go-sqlmock v1.5.0/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM=
@@ -81,7 +83,6 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXY
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
-github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Percona-Lab/go-grpc-prometheus v0.0.0-20230116133345-3487748d4592 h1:i7HDf+zPQvaPdrbLGS+wz/Ta32SszwYyHfJks1oVFzg=
github.com/Percona-Lab/go-grpc-prometheus v0.0.0-20230116133345-3487748d4592/go.mod h1:xCJfGpj56ERA85Mj1VfBzoeWW4lZ00xXXkvG0LJQjZU=
github.com/Percona-Lab/kingpin v2.2.6-percona+incompatible h1:N5oM40aAatvf8bCYjv69YsVdxJLIUhY/MerUG1jRL9Y=
@@ -91,10 +92,12 @@ github.com/Percona-Lab/spec v0.20.5-percona/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5i
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
github.com/alecthomas/assert/v2 v2.1.0 h1:tbredtNcQnoSd3QBhQWI7QZ3XHOVkw1Moklp2ojoH/0=
+github.com/alecthomas/assert/v2 v2.1.0/go.mod h1:b/+1DI2Q6NckYi+3mXyH3wFb8qG37K/DuK80n7WefXA=
github.com/alecthomas/kingpin v2.2.6+incompatible/go.mod h1:59OFYbFVLKQKq+mqrL6Rw5bR0c3ACQaawgXx0QYndlE=
github.com/alecthomas/kong v0.8.0 h1:ryDCzutfIqJPnNn0omnrgHLbAggDQM2VWHikE1xqK7s=
github.com/alecthomas/kong v0.8.0/go.mod h1:n1iCIO2xS46oE8ZfYCNDqdR0b0wZNrXAIAqro/2132U=
github.com/alecthomas/repr v0.1.0 h1:ENn2e1+J3k09gyj2shc0dHr/yjaWSHRlrJ4DPMevDqE=
+github.com/alecthomas/repr v0.1.0/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8=
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=
@@ -106,17 +109,14 @@ github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8V
github.com/andybalholm/brotli v1.0.5 h1:8uQZIdzKmjc/iuPu7O2ioW48L81FgatrcpfFmiq/cCs=
github.com/andybalholm/brotli v1.0.5/go.mod h1:fO7iG3H7G2nSZ7m0zPUDn85XEX2GTukHGRSepvi9Eig=
github.com/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
-github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so=
github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
-github.com/atotto/clipboard v0.1.4/go.mod h1:ZY9tmq7sm5xIbd9bOK4onWV4S6X0u6GY7Vn0Yu86PYI=
github.com/aws/aws-sdk-go v1.22.1/go.mod h1:KmX6BPdI08NWTb3/sm4ZGu5ShLoqVDhKgpiN924inxo=
github.com/aws/aws-sdk-go v1.34.28/go.mod h1:H7NKnBqNVzoTJpGfLrQkkD+ytBA93eiDYi/+8rV9s48=
github.com/aws/aws-sdk-go v1.40.7/go.mod h1:585smgzpB/KqRA+K3y/NL/oYRqQvpNJYvLm+LY1U59Q=
-github.com/aws/aws-sdk-go v1.44.273 h1:CX8O0gK+cGrgUyv7bgJ6QQP9mQg7u5mweHdNzULH47c=
-github.com/aws/aws-sdk-go v1.44.273/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
-github.com/aymanbagabas/go-osc52 v1.0.3/go.mod h1:zT8H+Rk4VSabYN90pWyugflM3ZhpTZNC7cASDfUCdT4=
+github.com/aws/aws-sdk-go v1.45.2 h1:hTong9YUklQKqzrGk3WnKABReb5R8GjbG4Y6dEQfjnk=
+github.com/aws/aws-sdk-go v1.45.2/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI=
github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k=
github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8=
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
@@ -132,24 +132,20 @@ github.com/blang/semver/v4 v4.0.0 h1:1PFHFE6yCCTv8C1TeyNNarDzntLi7wMI5i/pzqYIsAM
github.com/blang/semver/v4 v4.0.0/go.mod h1:IbckMUScFkM3pff0VJDNKRiT6TG/YpiHIM2yvyW5YoQ=
github.com/brianvoe/gofakeit v3.18.0+incompatible h1:wDOmHc9DLG4nRjUVVaxA+CEglKOW72Y5+4WNxUIkjM8=
github.com/brianvoe/gofakeit v3.18.0+incompatible/go.mod h1:kfwdRA90vvNhPutZWfH7WPaDzUjz+CZFqG+rPkOjGOc=
-github.com/brianvoe/gofakeit/v6 v6.22.0 h1:BzOsDot1o3cufTfOk+fWKE9nFYojyDV+XHdCWL2+uyE=
-github.com/brianvoe/gofakeit/v6 v6.22.0/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8=
-github.com/buger/jsonparser v1.1.1/go.mod h1:6RYKKt7H4d4+iWqouImQ9R2FZql3VbhNgx27UK13J/0=
+github.com/brianvoe/gofakeit/v6 v6.23.0 h1:pgVhyWpYq4e0GEVCh2gdZnS/nBX+8SnyTBliHg5xjks=
+github.com/brianvoe/gofakeit/v6 v6.23.0/go.mod h1:Ow6qC71xtwm79anlwKRlWZW6zVq9D2XHE4QSSMP/rU8=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
-github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
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/charmbracelet/bubbles v0.15.0 h1:c5vZ3woHV5W2b8YZI1q7v4ZNQaPetfHuoHzx+56Z6TI=
-github.com/charmbracelet/bubbles v0.15.0/go.mod h1:Y7gSFbBzlMpUDR/XM9MhZI374Q+1p1kluf1uLl8iK74=
-github.com/charmbracelet/bubbletea v0.23.1/go.mod h1:JAfGK/3/pPKHTnAS8JIE2u9f61BjWTQY57RbT25aMXU=
-github.com/charmbracelet/bubbletea v0.24.0 h1:l8PHrft/GIeikDPCUhQe53AJrDD8xGSn0Agirh8xbe8=
-github.com/charmbracelet/bubbletea v0.24.0/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg=
+github.com/charmbracelet/bubbles v0.16.1 h1:6uzpAAaT9ZqKssntbvZMlksWHruQLNxg49H5WdeuYSY=
+github.com/charmbracelet/bubbles v0.16.1/go.mod h1:2QCp9LFlEsBQMvIYERr7Ww2H2bA7xen1idUDIzm/+Xc=
+github.com/charmbracelet/bubbletea v0.24.1 h1:LpdYfnu+Qc6XtvMz6d/6rRY71yttHTP5HtrjMgWvixc=
+github.com/charmbracelet/bubbletea v0.24.1/go.mod h1:rK3g/2+T8vOSEkNHvtq40umJpeVYDn6bLaqbgzhL/hg=
github.com/charmbracelet/harmonica v0.2.0 h1:8NxJWRWg/bzKqqEaaeFNipOu77YR5t8aSwG4pgaUBiQ=
github.com/charmbracelet/harmonica v0.2.0/go.mod h1:KSri/1RMQOZLbw7AHqgcBycp8pgJnQMYYT8QZRqZ1Ao=
-github.com/charmbracelet/lipgloss v0.6.0/go.mod h1:tHh2wr34xcHjC2HCXIlGSG1jaDF0S0atAUvBMP6Ppuk=
-github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E=
-github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c=
+github.com/charmbracelet/lipgloss v0.8.0 h1:IS00fk4XAHcf8uZKc3eHeMUTCxUH6NkaTrdyCQk84RU=
+github.com/charmbracelet/lipgloss v0.8.0/go.mod h1:p4eYUZZJ/0oXTuCQKFF8mqyKCz0ja6y+7DniDDw5KKU=
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=
@@ -157,10 +153,7 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58 h1:F1EaeKL/ta07PY/k9Os/UFtwERei2/XzGemhpGnBKNg=
github.com/cloudflare/golz4 v0.0.0-20150217214814-ef862a3cdc58/go.mod h1:EOBUe0h4xcZ5GoxqC5SDxFQ8gwyZPKQoEzownBlhI80=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
-github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
-github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
-github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81 h1:q2hJAaP1k2wIvVRd/hEHD7lacgqrCPS+k8g1MndzfWY=
github.com/containerd/console v1.0.4-0.20230313162750-1ae8d489ac81/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk=
github.com/craiggwilson/goke v0.0.0-20200309222237-69a77cdfe646/go.mod h1:IX+FckvUr3c6SNWSzspUD94HqCMFCW+sIK0lJGSkWkg=
@@ -172,7 +165,9 @@ github.com/denisenkom/go-mssqldb v0.9.0 h1:RSohk2RsiZqLZ0zCjtfn3S4Gp4exhpBWHyQ7D
github.com/denisenkom/go-mssqldb v0.9.0/go.mod h1:xbL0rPBG9cCiLr28tMa8zpbdarY27NDyej4t/EjAShU=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dhui/dktest v0.3.16 h1:i6gq2YQEtcrjKbeJpBkWjE8MmLZPYllcjOFbTZuPDnw=
+github.com/dhui/dktest v0.3.16/go.mod h1:gYaA3LRmM8Z4vJl2MA0THIigJoZrwOansEOsp+kqxp0=
github.com/dnaeon/go-vcr v1.2.0 h1:zHCHvJYTMh1N7xnV7zf1m1GPBF9Ad0Jk/whtQ1663qI=
+github.com/dnaeon/go-vcr v1.2.0/go.mod h1:R4UdLID7HZT3taECzJs4YgbbH6PIGXB6W/sc5OLb6RQ=
github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
@@ -184,7 +179,6 @@ github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5Xh
github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
-github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE=
github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY=
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/emicklei/go-restful/v3 v3.9.0 h1:XwGDlfxEnQZzuopoqxwSEllNcCOM9DhhFyhFIIGKwxE=
@@ -192,23 +186,20 @@ github.com/emicklei/go-restful/v3 v3.9.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry
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/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
-github.com/envoyproxy/go-control-plane v0.9.9-0.20210512163311-63b5d3c536b0/go.mod h1:hliV/p42l8fGbc6Y9bQ70uLwIvmJyVE5k4iMKlh8wCQ=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9Qwa1EK9LcD4jVUQ=
-github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs=
+github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
+github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
github.com/evanphx/json-patch v5.6.0+incompatible h1:jBYDEEiFBPxA0v50tFdvOzQQTCvpL6mnFh5mB2/l16U=
github.com/evanphx/json-patch v5.6.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww=
github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4=
-github.com/flowstack/go-jsonschema v0.1.1/go.mod h1:yL7fNggx1o8rm9RlgXv7hTBWxdBM0rVwpMwimd3F3N0=
github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
github.com/frankban/quicktest v1.5.0/go.mod h1:jaStnuzAqU1AJdCO0l53JDCJrVDKcS03DbaAcR7Ks/o=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
-github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/go-co-op/gocron v1.30.0 h1:7nDCO++3HqQb+gSyd0NWRjsNbyPcK9cKVepBQWWaP6E=
-github.com/go-co-op/gocron v1.30.0/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y=
+github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
+github.com/go-co-op/gocron v1.31.0 h1:8VaWk7ARDpsVYFP8SmjvHrBZQkcPQ7HyAzF7acG57yE=
+github.com/go-co-op/gocron v1.31.0/go.mod h1:39f6KNSGVOU1LO/ZOoZfcSxwlsJDQOKSu8erN0SH48Y=
github.com/go-errors/errors v1.4.2 h1:J6MZopCL4uSllY1OfXM374weqZFFItUbrImctkmUxIA=
github.com/go-errors/errors v1.4.2/go.mod h1:sIVyrIiJhuEF+Pj9Ebtd6P/rEYROXFi3BopGUQ5a5Og=
github.com/go-faster/city v1.0.1 h1:4WAxSZ3V2Ws4QRDrscLEDcibJY8uf41H6AhXDrNDcGw=
@@ -229,26 +220,27 @@ github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V
github.com/go-logfmt/logfmt v0.5.0/go.mod h1:wCYkCAKZfumFQihp8CzCvQ3paCTfi41vtzG1KdI/P7A=
github.com/go-logr/logr v1.2.0/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
-github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0=
-github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
+github.com/go-logr/logr v1.2.4 h1:g01GSCwiDw2xSZfjJ2/T9M+S6pFdcNtFYsp+Y43HYDQ=
+github.com/go-logr/logr v1.2.4/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag=
github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE=
github.com/go-logr/zapr v1.2.3 h1:a9vnzlIBPQBBkeaR9IuMUfmVOrQlkoC4YfPoFkX3T7A=
+github.com/go-logr/zapr v1.2.3/go.mod h1:eIauM6P8qSvTw5o2ez6UEAfGjQKrxQTl5EoK+Qa2oG4=
github.com/go-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY=
github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc=
github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo=
github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M=
-github.com/go-openapi/errors v0.20.3 h1:rz6kiC84sqNQoqrtulzaL/VERgkoCyB6WdEkc2ujzUc=
-github.com/go-openapi/errors v0.20.3/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk=
+github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M=
+github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk=
github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg=
github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE=
github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs=
github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo=
-github.com/go-openapi/jsonreference v0.20.1 h1:FBLnyygC4/IZZr893oiomc9XaghoveYTrLC1F86HID8=
-github.com/go-openapi/jsonreference v0.20.1/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
+github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE=
+github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k=
github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g=
github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro=
github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw=
@@ -272,7 +264,8 @@ github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LB
github.com/go-sql-driver/mysql v1.7.1 h1:lUIinVbN1DY0xBg0eMOzmmtGoHwWBbvnWubQUrtU8EI=
github.com/go-sql-driver/mysql v1.7.1/go.mod h1:OXbVy3sEdcQ2Doequ6Z5BW6fXNQTmx+9S1MCJN5yJMI=
github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572 h1:tfuBGBXKqDEevZMzYi5KSi8KkcZtzBcTgAUUtapy0OI=
+github.com/go-task/slim-sprig v0.0.0-20230315185526-52ccab3ef572/go.mod h1:9Pwr4B2jHnOSGXyyzV8ROjYa2ojvAY6HCGYYfMoC3Ls=
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b h1:/vQ+oYKu+JoyaMPDsv5FzwuL2wwWBgBbtj/YLCi4LuA=
github.com/gobs/pretty v0.0.0-20180724170744-09732c25a95b/go.mod h1:Xo4aNUOrJnVruqWQJBtW6+bTBDTniY8yZum5rF3b5jw=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
@@ -313,6 +306,7 @@ github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2V
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
+github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
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=
@@ -326,6 +320,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt
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/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
+github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
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=
@@ -341,7 +336,6 @@ github.com/golang/protobuf v1.4.1/go.mod h1:U8fpvMrcmy5pZrNK1lt4xCsGvpyWQ/VVv6QD
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/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
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/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
@@ -350,8 +344,8 @@ github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
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/gnostic v0.6.9 h1:ZK/5VhkoX835RikCHpSUJV9a+S3e1zLh59YnyWeBW+0=
-github.com/google/gnostic v0.6.9/go.mod h1:Nm8234We1lq6iB9OmlgNv3nH91XLLVZHCDayfA3xq+E=
+github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I=
+github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U=
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=
@@ -377,11 +371,11 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
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/pprof v0.0.0-20221118152302-e6195bd50e26 h1:Xim43kblpZXfIBQsbuBVKCudVG457BR2GZFIz3uw3hQ=
+github.com/google/pprof v0.0.0-20221118152302-e6195bd50e26/go.mod h1:dDKJzRmX4S37WGHujM7tX//fmj1uioxKzKxz3lo4HJo=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4=
github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.2.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
@@ -389,13 +383,12 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
-github.com/grafana/grafana-api-golang-client v0.23.0 h1:Uta0dSkxWYf1D83/E7MRLCG69387FiUc+k9U/35nMhY=
-github.com/grafana/grafana-api-golang-client v0.23.0/go.mod h1:24W29gPe9yl0/3A9X624TPkAOR8DpHno490cPwnkv8E=
+github.com/grafana/grafana-api-golang-client v0.24.0 h1:9cUvft7xCMnnL/Uscwy7eoldn16Gz5TH4T1MymuVs8E=
+github.com/grafana/grafana-api-golang-client v0.24.0/go.mod h1:24W29gPe9yl0/3A9X624TPkAOR8DpHno490cPwnkv8E=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0 h1:UH//fgunKIs4JdUbpDl1VZCDaL56wXCB/5+wF6uHfaI=
github.com/grpc-ecosystem/go-grpc-middleware v1.4.0/go.mod h1:g5qyo/la0ALbONm6Vbp88Yd8NsDy6rZz+RcrMPxvld8=
-github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I=
github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -409,6 +402,7 @@ github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09
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/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
+github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
@@ -465,10 +459,10 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv
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/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
-github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk=
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
+github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
@@ -495,22 +489,19 @@ github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqf
github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E=
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
-github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
-github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.18 h1:DOKFKCQ7FNG2L1rbrmstDN4QVRdS89Nkh85u68Uwp98=
github.com/mattn/go-isatty v0.0.18/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
-github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
-github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mattn/go-sqlite3 v1.9.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v1.14.16 h1:yOQRA0RpS5PFz/oikGwBEqvAWhWg5ufRz4ETLjwpU1Y=
+github.com/mattn/go-sqlite3 v1.14.16/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
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=
@@ -531,6 +522,7 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
+github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -545,17 +537,15 @@ github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJ
github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU=
github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
+github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b h1:1XF24mVaiu7u+CFywTdcDo2ie1pzzhwjt6RHqzpMU34=
github.com/muesli/ansi v0.0.0-20211018074035-2e021307bc4b/go.mod h1:fQuZ0gauxyBcmsdE3ZT4NasjaRdxmbCS0jRHsrWu3Ho=
github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELUXHmA=
github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
-github.com/muesli/reflow v0.2.1-0.20210115123740-9e1d0d53df68/go.mod h1:Xk+z4oIWdQqJzsxyjgl3P22oYZnHdZ8FFTHAQQt5BMQ=
github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
-github.com/muesli/termenv v0.11.1-0.20220204035834-5ac8409525e0/go.mod h1:Bd5NYQ7pd+SrtBSrSNoBBmXlcY8+Xj4BMJgh8qcZrvs=
-github.com/muesli/termenv v0.13.0/go.mod h1:sP1+uffeLaEYpyOTb8pLCUctGcGLnoFjSn4YJK5e2bc=
-github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs=
-github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ=
+github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
+github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
@@ -568,8 +558,10 @@ github.com/nsf/termbox-go v0.0.0-20160718140619-0723e7c3d0a3/go.mod h1:IuKpRQcYE
github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE=
-github.com/onsi/ginkgo/v2 v2.9.1 h1:zie5Ly042PD3bsCvsSOPvRnFwyo3rKe64TJlD6nu0mk=
-github.com/onsi/gomega v1.27.4 h1:Z2AnStgsdSayCMDiCU42qIz+HLqEPcgiOCXjAU/w+8E=
+github.com/onsi/ginkgo/v2 v2.9.4 h1:xR7vG4IXt5RWx6FfIjyAtsoMAtnc3C/rFXBBd2AjZwE=
+github.com/onsi/ginkgo/v2 v2.9.4/go.mod h1:gCQYp2Q+kSoIj7ykSVb9nskRSsR6PUj4AiLywzIhbKM=
+github.com/onsi/gomega v1.27.6 h1:ENqfyGeS5AX/rlXDd/ETokDz93u0YufY1Pgxuy/PvWE=
+github.com/onsi/gomega v1.27.6/go.mod h1:PIQNjfQwkP3aQAH7lf7j87O/5FiNr+ZR8+ipb+qQlhg=
github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQYUd2OVphdqWwCJHrFt2s=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
@@ -582,16 +574,16 @@ github.com/operator-framework/api v0.17.6 h1:E6+vlvYUKafvoXYtCuHlDZrXX4vl8AT+r93
github.com/operator-framework/api v0.17.6/go.mod h1:l/cuwtPxkVUY7fzYgdust2m9tlmb8I4pOvbsUufRb24=
github.com/operator-framework/operator-lifecycle-manager v0.24.0 h1:9LOfvyohGEkNHwcOGOgw+w3ZAnGeT6JVh3CvIbWpnus=
github.com/operator-framework/operator-lifecycle-manager v0.24.0/go.mod h1:2zDUxcpW2idTLjRw36WlMetHZ50Nlf1C3JxASPfYS20=
-github.com/paulmach/orb v0.9.0 h1:MwA1DqOKtvCgm7u9RZ/pnYejTeDJPnr0+0oFajBbJqk=
-github.com/paulmach/orb v0.9.0/go.mod h1:SudmOk85SXtmXAB3sLGyJ6tZy/8pdfrV0o6ef98Xc30=
+github.com/paulmach/orb v0.10.0 h1:guVYVqzxHE/CQ1KpfGO077TR0ATHSNjp4s6XGLn3W9s=
+github.com/paulmach/orb v0.10.0/go.mod h1:5mULz1xQfs3bmQm63QEJA6lNGujuRafwA5S/EnuLaLU=
github.com/paulmach/protoscan v0.2.1/go.mod h1:SpcSwydNLrxUGSDvXvO0P7g7AuhJ7lcKfDlhJCDw2gY=
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/percona-lab/crypto v0.0.0-20220811043533-d164de3c7f08 h1:NprWeXddFZJSgtN8hmf/hhIgiZwB3GNaKnI88iAFgEc=
github.com/percona-lab/crypto v0.0.0-20220811043533-d164de3c7f08/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
github.com/percona-platform/dbaas-api v0.0.0-20230103182808-d79c449a9f4c h1:1JySfwdjVfc9ahl0466OX7nSQ7Z4SjQkLe3ZdLkMOJI=
github.com/percona-platform/dbaas-api v0.0.0-20230103182808-d79c449a9f4c/go.mod h1:/jgle33awfHq1va/T6NnNS5wWAETSnl6wUZ1bew+CJ0=
-github.com/percona-platform/saas v0.0.0-20230306173543-c223f9a47342 h1:ilguq4u7k08QxS3UDYINt8x6+AOgB0wZApd1o4IK8rQ=
-github.com/percona-platform/saas v0.0.0-20230306173543-c223f9a47342/go.mod h1:gFUwaFp6Ugu5qsBwiOVJYbDlzgZ77tmXdXGO7tG5xVI=
+github.com/percona-platform/saas v0.0.0-20230728161159-ad6bdeb8a3d9 h1:KkOH+Y4sVRP7qvRtTDmfPFNjjQcwU2054/jNl9DZhEo=
+github.com/percona-platform/saas v0.0.0-20230728161159-ad6bdeb8a3d9/go.mod h1:lZuFcqj0EoQWx28SYkTcdhJOCQEbRcAyahYPfRMY7tc=
github.com/percona/dbaas-operator v0.1.6 h1:NsZXDKcPXk38kET+X6r8Es+3Supyu5XJZMS0gqPejKs=
github.com/percona/dbaas-operator v0.1.6/go.mod h1:52B/kh+Jmtfv0JiZgDcc34qgbwwEi9U4A3311JBxIZg=
github.com/percona/exporter_shared v0.7.4 h1:S+xnfK/CySiYqr4XqLiLAfO3rxgEOUFK+m6lCBi3mgc=
@@ -659,16 +651,15 @@ github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab h1:ZjX6I48eZSFetP
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab/go.mod h1:/PfPXh0EntGc3QAAyUaviy4S9tzy4Zp0e2ilq4voC6E=
github.com/robfig/cron/v3 v3.0.1 h1:WdRxkvbJztn8LMz/QEvLN5sBU+xKpSqwwUO1Pjr4qDs=
github.com/robfig/cron/v3 v3.0.1/go.mod h1:eQICP3HwyT7UooqI/z+Ov+PtYAWygg1TEWWzGIFLtro=
-github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc=
github.com/rogpeppe/go-internal v1.8.1/go.mod h1:JeRgkft04UBgHMgCIwADu4Pn6Mtm5d4nPKWu0nJ5d+o=
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/rs/xid v1.5.0 h1:mKX4bl4iPYJtEIxp6CYiUuLQ/8DYMoz0PUdtGgMFRVc=
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
-github.com/sahilm/fuzzy v0.1.0/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y=
github.com/segmentio/asm v1.2.0 h1:9BQrFxC+YOHJlTlHGkTrFWf59nbL3XnCoFLTwDCI7ys=
github.com/segmentio/asm v1.2.0/go.mod h1:BqMnlJP91P8d+4ibuonYZw9mfnzI9HfxselHZr5aAcs=
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
@@ -685,12 +676,10 @@ github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
-github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA=
github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
-github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
@@ -699,7 +688,6 @@ github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpE
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
-github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA=
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -719,11 +707,8 @@ github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6
github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8=
github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
-github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
-github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ=
-github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y=
-github.com/xlab/treeprint v1.1.0 h1:G/1DjNkPpfZCFt9CSh6b5/nY4VimlbHF3Rh4obvtzDk=
-github.com/xlab/treeprint v1.1.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
+github.com/xlab/treeprint v1.2.0 h1:HzHnuAF1plUN2zGlAFHbSQP2qJ0ZAD3XF5XD7OesXRQ=
+github.com/xlab/treeprint v1.2.0/go.mod h1:gj5Gd3gPdKtR1ikdDK6fnFLdmIS0X30kTTuNd/WEJu0=
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a h1:fZHgsYlfvtyqToslyjUt3VOPF4J7aK/3MPcK7xp3PDk=
github.com/youmark/pkcs8 v0.0.0-20201027041543-1326539a0a0a/go.mod h1:ul22v+Nro/R083muKhosV54bj5niojjWZvU8xrevuH4=
@@ -737,7 +722,7 @@ go.mongodb.org/mongo-driver v1.7.0/go.mod h1:Q4oFMbo1+MSNqICAdYMlC/zSTrwCogR4R8N
go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng=
go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8=
-go.mongodb.org/mongo-driver v1.11.1/go.mod h1:s7p5vEtfbeR1gYi6pnj3c3/urpbLv2T5Sfd6Rp2HBB8=
+go.mongodb.org/mongo-driver v1.11.4/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g=
go.mongodb.org/mongo-driver v1.12.0 h1:aPx33jmn/rQuJXPQLZQ8NtfPQG8CaqgLThFtqRb0PiE=
go.mongodb.org/mongo-driver v1.12.0/go.mod h1:AZkxhPnFJUoH7kZlFkVKucV20K387miPfm7oimrSmK0=
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
@@ -745,23 +730,27 @@ 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=
-go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM=
-go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU=
+go.opentelemetry.io/otel v1.16.0 h1:Z7GVAX/UkAXPKsy94IU+i6thsQS4nb7LviLpnaNeW8s=
+go.opentelemetry.io/otel v1.16.0/go.mod h1:vl0h9NUa1D5s1nv3A5vZOYWn8av4K8Ml6JDeHrT/bx4=
+go.opentelemetry.io/otel/metric v1.16.0 h1:RbrpwVG1Hfv85LgnZ7+txXioPDoh6EdbZHo26Q3hqOo=
+go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxxNYodqc4xnGCo4=
go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY=
-go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M=
-go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8=
-go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
-go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd h1:Uo/x0Ir5vQJ+683GXB9Ug+4fcjsbp7z7Ul8UaZbhsRM=
-go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd/go.mod h1:t3mmBBPzAVvK0L0n1drDmrQsJ8FoIx4INCqVMTr/Zo0=
+go.opentelemetry.io/otel/sdk v1.14.0/go.mod h1:bwIC5TjrNG6QDCHNWvW4HLHtUQ4I+VQDsnjhvyZCALM=
+go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
+go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
+go.starlark.net v0.0.0-20230717150657-8a3343210976 h1:7ljYNcZU84T2N0tZdDgvL7U3M4iFmglAUUU1gRFE/2Q=
+go.starlark.net v0.0.0-20230717150657-8a3343210976/go.mod h1:jxU+3+j+71eXOW14274+SmmuW82qJzl6iZSeqEtTGds=
go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
go.uber.org/atomic v1.9.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc=
-go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ=
-go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
+go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
+go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A=
go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU=
go.uber.org/multierr v1.9.0 h1:7fIwc/ZtS0q++VgcfqFDxSBZVv/Xo49/SYnDFupUwlI=
+go.uber.org/multierr v1.9.0/go.mod h1:X2jQV1h+kxSjClGpnseKVIxpmcjrj7MNnI0bnlfKTVQ=
go.uber.org/zap v1.18.1/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
+go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -800,8 +789,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
-golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
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=
@@ -832,23 +821,21 @@ golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81R
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-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
-golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco=
-golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
-golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
+golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
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.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
-golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
+golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
+golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
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/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -905,29 +892,26 @@ golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-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-20210616045830-e2b7044e8c71/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220704084225-05e143d24a9e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
+golang.org/x/sys v0.12.0/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/term v0.0.0-20220526004731-065cf7ba2467/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
-golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
+golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
+golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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=
@@ -940,8 +924,8 @@ golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
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=
@@ -1000,13 +984,14 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
-golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
+golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
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=
gomodules.xyz/jsonpatch/v2 v2.2.0 h1:4pT439QV83L+G9FkcCriY6EkpcK6r6bK+A5FBUMI7qY=
+gomodules.xyz/jsonpatch/v2 v2.2.0/go.mod h1:WXp+iVDkoLQqPudfQ9GBlwB2eZ5DKOnjQZCYdOS8GPY=
gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM=
gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
@@ -1060,20 +1045,18 @@ google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfG
google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/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-20200513103714-09dca8ec2884/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/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc=
-google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e h1:Ao9GzfUMPH3zjVfzXG5rlWlk+Q8MXWKwWpwVQE1MXfw=
-google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk=
-google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM=
-google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
+google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5 h1:L6iMMGrtzgHsWofoFcihmDEMYeDR9KN/ThbPWGrh++g=
+google.golang.org/genproto v0.0.0-20230803162519-f966b187b2e5/go.mod h1:oH/ZOT02u4kWEp7oYBGYFFkCdKS/uYR9Z7+0/xuuFp8=
+google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q=
+google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
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=
@@ -1086,11 +1069,8 @@ google.golang.org/grpc v1.28.0/go.mod h1:rpkK4SK4GF4Ach/+MFLZUBavHOvF2JJB5uozKKa
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/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
-google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34=
-google.golang.org/grpc v1.57.0-dev h1:XCvzqke2TBzQUs3a1MO1VsqVkWeAdJ/KmxHCAVtPpe8=
-google.golang.org/grpc v1.57.0-dev/go.mod h1:ZPf89/axrdgRDfHqb7fa0GF5t4VUER0vWnqnPNuRP7k=
+google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o=
+google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
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=
@@ -1123,7 +1103,6 @@ gopkg.in/reform.v1 v1.5.1/go.mod h1:AIv0CbDRJ0ljQwptGeaIXfpDRo02uJwTq92aMFELEeU=
gopkg.in/tomb.v2 v2.0.0-20140626144623-14b3d72120e8/go.mod h1:BHsqpu/nsuzkT5BpiH1EMZPLyqSMM8JbIavyFACoFNk=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.5/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -1145,24 +1124,24 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
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=
-k8s.io/api v0.27.2 h1:+H17AJpUMvl+clT+BPnKf0E3ksMAzoBBg7CntpSuADo=
-k8s.io/api v0.27.2/go.mod h1:ENmbocXfBT2ADujUXcBhHV55RIT31IIEvkntP6vZKS4=
+k8s.io/api v0.28.0 h1:3j3VPWmN9tTDI68NETBWlDiA9qOiGJ7sdKeufehBYsM=
+k8s.io/api v0.28.0/go.mod h1:0l8NZJzB0i/etuWnIXcwfIv+xnDOhL3lLW919AWYDuY=
k8s.io/apiextensions-apiserver v0.26.2 h1:/yTG2B9jGY2Q70iGskMf41qTLhL9XeNN2KhI0uDgwko=
k8s.io/apiextensions-apiserver v0.26.2/go.mod h1:Y7UPgch8nph8mGCuVk0SK83LnS8Esf3n6fUBgew8SH8=
-k8s.io/apimachinery v0.27.2 h1:vBjGaKKieaIreI+oQwELalVG4d8f3YAMNpWLzDXkxeg=
-k8s.io/apimachinery v0.27.2/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E=
-k8s.io/cli-runtime v0.27.2 h1:9HI8gfReNujKXt16tGOAnb8b4NZ5E+e0mQQHKhFGwYw=
-k8s.io/cli-runtime v0.27.2/go.mod h1:9UecpyPDTkhiYY4d9htzRqN+rKomJgyb4wi0OfrmCjw=
-k8s.io/client-go v0.27.2 h1:vDLSeuYvCHKeoQRhCXjxXO45nHVv2Ip4Fe0MfioMrhE=
-k8s.io/client-go v0.27.2/go.mod h1:tY0gVmUsHrAmjzHX9zs7eCjxcBsf8IiNe7KQ52biTcQ=
-k8s.io/klog/v2 v2.90.1 h1:m4bYOKall2MmOiRaR1J+We67Do7vm9KiQVlT96lnHUw=
-k8s.io/klog/v2 v2.90.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
-k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f h1:2kWPakN3i/k81b0gvD5C5FJ2kxm1WrQFanWchyKuqGg=
-k8s.io/kube-openapi v0.0.0-20230501164219-8b0f38b5fd1f/go.mod h1:byini6yhqGC14c3ebc/QwanvYwhuMWF6yz2F8uwW8eg=
-k8s.io/kubectl v0.27.2 h1:sSBM2j94MHBFRWfHIWtEXWCicViQzZsb177rNsKBhZg=
-k8s.io/kubectl v0.27.2/go.mod h1:GCOODtxPcrjh+EC611MqREkU8RjYBh10ldQCQ6zpFKw=
-k8s.io/utils v0.0.0-20230209194617-a36077c30491 h1:r0BAOLElQnnFhE/ApUsg3iHdVYYPBjNSSOMowRZxxsY=
-k8s.io/utils v0.0.0-20230209194617-a36077c30491/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
+k8s.io/apimachinery v0.28.0 h1:ScHS2AG16UlYWk63r46oU3D5y54T53cVI5mMJwwqFNA=
+k8s.io/apimachinery v0.28.0/go.mod h1:X0xh/chESs2hP9koe+SdIAcXWcQ+RM5hy0ZynB+yEvw=
+k8s.io/cli-runtime v0.28.0 h1:Tcz1nnccXZDNIzoH6EwjCs+7ezkUGhorzCweEvlVOFg=
+k8s.io/cli-runtime v0.28.0/go.mod h1:U+ySmOKBm/JUCmebhmecXeTwNN1RzI7DW4+OM8Oryas=
+k8s.io/client-go v0.28.0 h1:ebcPRDZsCjpj62+cMk1eGNX1QkMdRmQ6lmz5BLoFWeM=
+k8s.io/client-go v0.28.0/go.mod h1:0Asy9Xt3U98RypWJmU1ZrRAGKhP6NqDPmptlAzK2kMc=
+k8s.io/klog/v2 v2.100.1 h1:7WCHKK6K8fNhTqfBhISHQ97KrnJNFZMcQvKp7gP/tmg=
+k8s.io/klog/v2 v2.100.1/go.mod h1:y1WjHnz7Dj687irZUWR/WLkLc5N1YHtjLdmgWjndZn0=
+k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9 h1:LyMgNKD2P8Wn1iAwQU5OhxCKlKJy0sHc+PcDwFB24dQ=
+k8s.io/kube-openapi v0.0.0-20230717233707-2695361300d9/go.mod h1:wZK2AVp1uHCp4VamDVgBP2COHZjqD1T68Rf0CM3YjSM=
+k8s.io/kubectl v0.28.0 h1:qhfju0OaU+JGeBlToPeeIg2UJUWP++QwTkpio6nlPKg=
+k8s.io/kubectl v0.28.0/go.mod h1:1We+E5nSX3/TVoSQ6y5Bzld5OhTBHZHlKEYl7g/NaTk=
+k8s.io/utils v0.0.0-20230406110748-d93618cff8a2 h1:qY1Ad8PODbnymg2pRbkyMT/ylpTrCM8P2RJ0yroCyIk=
+k8s.io/utils v0.0.0-20230406110748-d93618cff8a2/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
lukechampine.com/uint128 v1.2.0 h1:mBi/5l91vocEN8otkC5bDLhi2KdCticRiwbdB0O+rjI=
lukechampine.com/uint128 v1.2.0/go.mod h1:c4eWIwlEGaxC/+H1VguhU4PHXNWDCDMUlWdIWl2j1gk=
modernc.org/cc/v3 v3.40.0 h1:P3g79IUS/93SYhtoeaHW+kRCIrYaxJ27MFPv+7kaTOw=
@@ -1170,23 +1149,27 @@ modernc.org/cc/v3 v3.40.0/go.mod h1:/bTg4dnWkSXowUO6ssQKnOV0yMVxDYNIsIrzqTFDGH0=
modernc.org/ccgo/v3 v3.16.13 h1:Mkgdzl46i5F/CNR/Kj80Ri59hC8TKAhZrYSaqvkwzUw=
modernc.org/ccgo/v3 v3.16.13/go.mod h1:2Quk+5YgpImhPjv2Qsob1DnZ/4som1lJTodubIcoUkY=
modernc.org/ccorpus v1.11.6 h1:J16RXiiqiCgua6+ZvQot4yUuUy8zxgqbqEEUuGPlISk=
+modernc.org/ccorpus v1.11.6/go.mod h1:2gEUTrWqdpH2pXsmTM1ZkjeSrUWDpjMu2T6m29L/ErQ=
modernc.org/httpfs v1.0.6 h1:AAgIpFZRXuYnkjftxTAZwMIiwEqAfk8aVB2/oA6nAeM=
-modernc.org/libc v1.22.5 h1:91BNch/e5B0uPbJFgqbxXuOnxBQjlS//icfQEGmvyjE=
-modernc.org/libc v1.22.5/go.mod h1:jj+Z7dTNX8fBScMVNRAYZ/jF91K8fdT2hYMThc3YjBY=
+modernc.org/httpfs v1.0.6/go.mod h1:7dosgurJGp0sPaRanU53W4xZYKh14wfzX420oZADeHM=
+modernc.org/libc v1.24.1 h1:uvJSeCKL/AgzBo2yYIPPTy82v21KgGnizcGYfBHaNuM=
+modernc.org/libc v1.24.1/go.mod h1:FmfO1RLrU3MHJfyi9eYYmZBfi/R+tqZ6+hQ3yQQUkak=
modernc.org/mathutil v1.5.0 h1:rV0Ko/6SfM+8G+yKiyI830l3Wuz1zRutdslNoQ0kfiQ=
modernc.org/mathutil v1.5.0/go.mod h1:mZW8CKdRPY1v87qxC/wUdX5O1qDzXMP5TH3wjfpga6E=
-modernc.org/memory v1.5.0 h1:N+/8c5rE6EqugZwHii4IFsaJ7MUhoWX07J5tC/iI5Ds=
-modernc.org/memory v1.5.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
+modernc.org/memory v1.6.0 h1:i6mzavxrE9a30whzMfwf7XWVODx2r5OYXvU46cirX7o=
+modernc.org/memory v1.6.0/go.mod h1:PkUhL0Mugw21sHPeskwZW4D6VscE/GQJOnIpCnW6pSU=
modernc.org/opt v0.1.3 h1:3XOZf2yznlhC+ibLltsDGzABUGVx8J6pnFMS3E4dcq4=
modernc.org/opt v0.1.3/go.mod h1:WdSiB5evDcignE70guQKxYUl14mgWtbClRi5wmkkTX0=
-modernc.org/sqlite v1.23.0 h1:MWTFBI5H1WLnXpNBh/BTruBVqzzoh28DA0iOnlkkRaM=
-modernc.org/sqlite v1.23.0/go.mod h1:OrDj17Mggn6MhE+iPbBNf7RGKODDE9NFT0f3EwDzJqk=
+modernc.org/sqlite v1.25.0 h1:AFweiwPNd/b3BoKnBOfFm+Y260guGMF+0UFk0savqeA=
+modernc.org/sqlite v1.25.0/go.mod h1:FL3pVXie73rg3Rii6V/u5BoHlSoyeZeIgKZEgHARyCU=
modernc.org/strutil v1.1.3 h1:fNMm+oJklMGYfU9Ylcywl0CO5O6nTfaowNsh2wpPjzY=
modernc.org/strutil v1.1.3/go.mod h1:MEHNA7PdEnEwLvspRMtWTNnp2nnyvMfkimT1NKNAGbw=
modernc.org/tcl v1.15.2 h1:C4ybAYCGJw968e+Me18oW55kD/FexcHbqH2xak1ROSY=
+modernc.org/tcl v1.15.2/go.mod h1:3+k/ZaEbKrC8ePv8zJWPtBSW0V7Gg9g8rkmhI1Kfs3c=
modernc.org/token v1.0.1 h1:A3qvTqOwexpfZZeyI0FeGPDlSWX5pjZu9hF4lU+EKWg=
modernc.org/token v1.0.1/go.mod h1:UGzOrNV1mAFSEB63lOFHIpNRUVMvYTc6yu1SMY/XTDM=
modernc.org/z v1.7.3 h1:zDJf6iHjrnB+WRD88stbXokugjyc0/pB91ri1gO6LZY=
+modernc.org/z v1.7.3/go.mod h1:Ipv4tsdxZRbQyLq9Q1M6gdbkxYzdlrciF2Hi/lS7nWE=
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=
rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4=
rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0=
@@ -1195,10 +1178,10 @@ sigs.k8s.io/controller-runtime v0.14.6 h1:oxstGVvXGNnMvY7TAESYk+lzr6S3V5VFxQ6d92
sigs.k8s.io/controller-runtime v0.14.6/go.mod h1:WqIdsAY6JBsjfc/CqO0CORmNtoCtE4S6qbPc9s68h+0=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd h1:EDPBXCAspyGV4jQlpZSudPeMmr1bNJefnuqLsRAsHZo=
sigs.k8s.io/json v0.0.0-20221116044647-bc3834ca7abd/go.mod h1:B8JuhiUyNFVKdsE8h686QcCxMaH6HrOAZj4vswFpcB0=
-sigs.k8s.io/kustomize/api v0.13.2 h1:kejWfLeJhUsTGioDoFNJET5LQe/ajzXhJGYoU+pJsiA=
-sigs.k8s.io/kustomize/api v0.13.2/go.mod h1:DUp325VVMFVcQSq+ZxyDisA8wtldwHxLZbr1g94UHsw=
-sigs.k8s.io/kustomize/kyaml v0.14.1 h1:c8iibius7l24G2wVAGZn/Va2wNys03GXLjYVIcFVxKA=
-sigs.k8s.io/kustomize/kyaml v0.14.1/go.mod h1:AN1/IpawKilWD7V+YvQwRGUvuUOOWpjsHu6uHwonSF4=
+sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3 h1:XX3Ajgzov2RKUdc5jW3t5jwY7Bo7dcRm+tFxT+NfgY0=
+sigs.k8s.io/kustomize/api v0.13.5-0.20230601165947-6ce0bf390ce3/go.mod h1:9n16EZKMhXBNSiUC5kSdFQJkdH3zbxS/JoO619G1VAY=
+sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3 h1:W6cLQc5pnqM7vh3b7HvGNfXrJ/xL6BDMS0v1V/HHg5U=
+sigs.k8s.io/kustomize/kyaml v0.14.3-0.20230601165947-6ce0bf390ce3/go.mod h1:JWP1Fj0VWGHyw3YUPjXSQnRnrwezrZSrApfX5S0nIag=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3 h1:PRbqxJClWWYMNV1dhaG4NsibJbArud9kFxnAMREiWFE=
sigs.k8s.io/structured-merge-diff/v4 v4.2.3/go.mod h1:qjx8mGObPmV2aSZepjQjbmb2ihdVs8cGKBraizNC69E=
sigs.k8s.io/yaml v1.3.0 h1:a2VclLzOGrwOHDiV8EfBGhvjHvP46CtW5j6POvhYGGo=
diff --git a/managed/Makefile b/managed/Makefile
index 9412255408..5c3722002d 100644
--- a/managed/Makefile
+++ b/managed/Makefile
@@ -36,6 +36,10 @@ release: ## Build pmm-managed release binaries
env CGO_ENABLED=0 go build -v $(PMM_LD_FLAGS) -o $(PMM_RELEASE_PATH)/ ./cmd/...
$(PMM_RELEASE_PATH)/pmm-managed --version
+release-starlark:
+ env CGO_ENABLED=0 go build -v $(PMM_LD_FLAGS) -o $(PMM_RELEASE_PATH)/ ./cmd/pmm-managed-starlark/...
+ $(PMM_RELEASE_PATH)/pmm-managed-starlark --version
+
ARCH=$(shell uname -m)
release-dev: ## Build pmm-managed binaries for development
if [ $(ARCH) = "aarch64" ]; then \
diff --git a/managed/cmd/pmm-managed-init/main.go b/managed/cmd/pmm-managed-init/main.go
index f04f7efe0a..1d52155db1 100644
--- a/managed/cmd/pmm-managed-init/main.go
+++ b/managed/cmd/pmm-managed-init/main.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -24,7 +24,7 @@ import (
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services/supervisord"
"github.com/percona/pmm/managed/utils/envvars"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
)
func main() {
diff --git a/managed/cmd/pmm-managed-starlark/main.go b/managed/cmd/pmm-managed-starlark/main.go
index 5c23efab3e..f976d67a7f 100644
--- a/managed/cmd/pmm-managed-starlark/main.go
+++ b/managed/cmd/pmm-managed-starlark/main.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -33,7 +33,7 @@ import (
"github.com/percona/pmm/api/agentpb"
"github.com/percona/pmm/managed/services/checks"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
"github.com/percona/pmm/version"
)
@@ -129,13 +129,13 @@ func runChecks(l *logrus.Entry, data *checks.StarlarkScriptData) ([]check.Result
if !ok {
return nil, errors.Errorf("unexpected query result type: %T", dbQr)
}
- if dbRes[dbName], err = unmarshallQueryResult(s); err != nil {
+ if dbRes[dbName], err = unmarshalQueryResult(s); err != nil {
return nil, err
}
}
res[i] = dbRes
case string: // used for all other databases
- if res[i], err = unmarshallQueryResult(qr); err != nil {
+ if res[i], err = unmarshalQueryResult(qr); err != nil {
return nil, err
}
default:
@@ -158,7 +158,7 @@ func runChecks(l *logrus.Entry, data *checks.StarlarkScriptData) ([]check.Result
return results, nil
}
-func unmarshallQueryResult(qr string) ([]map[string]any, error) {
+func unmarshalQueryResult(qr string) ([]map[string]any, error) {
b, err := base64.StdEncoding.DecodeString(qr)
if err != nil {
return nil, errors.Wrap(err, "failed to decode base64 encoded query result")
diff --git a/managed/cmd/pmm-managed-starlark/main_test.go b/managed/cmd/pmm-managed-starlark/main_test.go
index f52f76ce86..ecb2dde83a 100644
--- a/managed/cmd/pmm-managed-starlark/main_test.go
+++ b/managed/cmd/pmm-managed-starlark/main_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -17,10 +17,12 @@ package main
import (
"bytes"
+ "context"
"encoding/json"
"os"
"os/exec"
"testing"
+ "time"
"github.com/percona-platform/saas/pkg/check"
"github.com/stretchr/testify/assert"
@@ -35,7 +37,7 @@ const (
// Possible errors:
// fatal error: runtime: out of memory
- // fatal error: out of memory allocating heap arena metadata
+ // fatal error: out of memory allocating heap arena metadatai.
memoryConsumingScriptStderr = "out of memory"
)
@@ -103,8 +105,13 @@ func TestStarlarkSandbox(t *testing.T) { //nolint:tparallel
},
}
+ ctx, cancel := context.WithTimeout(context.Background(), 120*time.Second)
+ t.Cleanup(cancel)
// since we run the binary as a child process to test it we need to build it first.
- err := exec.Command("make", "-C", "../..", "release").Run()
+ command := exec.CommandContext(ctx, "make", "-C", "../..", "release-starlark")
+ command.Stdout = os.Stdout
+ command.Stderr = os.Stderr
+ err := command.Run()
require.NoError(t, err)
for _, tc := range testCases {
diff --git a/managed/cmd/pmm-managed/main.go b/managed/cmd/pmm-managed/main.go
index 17ea63ccbb..c49c60544f 100644
--- a/managed/cmd/pmm-managed/main.go
+++ b/managed/cmd/pmm-managed/main.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -49,6 +49,7 @@ import (
"golang.org/x/sync/semaphore"
"golang.org/x/sys/unix"
"google.golang.org/grpc"
+ "google.golang.org/grpc/backoff"
channelz "google.golang.org/grpc/channelz/service"
"google.golang.org/grpc/credentials/insecure"
"google.golang.org/grpc/grpclog"
@@ -87,6 +88,7 @@ import (
"github.com/percona/pmm/managed/services/management"
"github.com/percona/pmm/managed/services/management/alerting"
managementbackup "github.com/percona/pmm/managed/services/management/backup"
+ "github.com/percona/pmm/managed/services/management/common"
managementdbaas "github.com/percona/pmm/managed/services/management/dbaas"
managementgrpc "github.com/percona/pmm/managed/services/management/grpc"
"github.com/percona/pmm/managed/services/minio"
@@ -104,9 +106,9 @@ import (
"github.com/percona/pmm/managed/utils/clean"
"github.com/percona/pmm/managed/utils/envvars"
"github.com/percona/pmm/managed/utils/interceptors"
- "github.com/percona/pmm/managed/utils/logger"
platformClient "github.com/percona/pmm/managed/utils/platform"
pmmerrors "github.com/percona/pmm/utils/errors"
+ "github.com/percona/pmm/utils/logger"
"github.com/percona/pmm/utils/sqlmetrics"
"github.com/percona/pmm/version"
)
@@ -255,8 +257,13 @@ func runGRPCServer(ctx context.Context, deps *gRPCServerDeps) {
deps.db, deps.agentsRegistry, deps.agentsStateUpdater,
deps.vmdb, deps.connectionCheck, deps.agentService)
+ mgmtBackupsService := managementbackup.NewBackupsService(deps.db, deps.backupService, deps.compatibilityService, deps.schedulerService)
+ mgmtArtifactsService := managementbackup.NewArtifactsService(deps.db, deps.backupRemovalService, deps.pbmPITRService)
+ mgmtRestoreHistoryService := managementbackup.NewRestoreHistoryService(deps.db)
+ mgmtServices := common.MgmtServices{BackupsService: mgmtBackupsService, ArtifactsService: mgmtArtifactsService, RestoreHistoryService: mgmtRestoreHistoryService}
+
inventorypb.RegisterNodesServer(gRPCServer, inventorygrpc.NewNodesServer(nodesSvc))
- inventorypb.RegisterServicesServer(gRPCServer, inventorygrpc.NewServicesServer(servicesSvc))
+ inventorypb.RegisterServicesServer(gRPCServer, inventorygrpc.NewServicesServer(servicesSvc, mgmtServices))
inventorypb.RegisterAgentsServer(gRPCServer, inventorygrpc.NewAgentsServer(agentsSvc))
nodeSvc := management.NewNodeService(deps.db, deps.grafanaClient)
@@ -288,10 +295,10 @@ func runGRPCServer(ctx context.Context, deps *gRPCServerDeps) {
alertingpb.RegisterAlertingServer(gRPCServer, deps.templatesService)
- backuppb.RegisterBackupsServer(gRPCServer, managementbackup.NewBackupsService(deps.db, deps.backupService, deps.compatibilityService, deps.schedulerService))
+ backuppb.RegisterBackupsServer(gRPCServer, mgmtBackupsService)
backuppb.RegisterLocationsServer(gRPCServer, managementbackup.NewLocationsService(deps.db, deps.minioClient))
- backuppb.RegisterArtifactsServer(gRPCServer, managementbackup.NewArtifactsService(deps.db, deps.backupRemovalService, deps.pbmPITRService))
- backuppb.RegisterRestoreHistoryServer(gRPCServer, managementbackup.NewRestoreHistoryService(deps.db))
+ backuppb.RegisterArtifactsServer(gRPCServer, mgmtArtifactsService)
+ backuppb.RegisterRestoreHistoryServer(gRPCServer, mgmtRestoreHistoryService)
k8sServer := managementdbaas.NewKubernetesServer(deps.db, deps.dbaasClient, deps.versionServiceClient, deps.grafanaClient)
deps.dbaasInitializer.RegisterKubernetesServer(k8sServer)
@@ -548,15 +555,15 @@ func setup(ctx context.Context, deps *setupDeps) bool {
deps.l.Infof("Updating supervisord configuration...")
settings, err := models.GetSettings(db.Querier)
if err != nil {
- deps.l.Warnf("Failed to get settings: %+v.", err)
+ deps.l.Warnf("Failed to get settings: %s.", err)
return false
}
ssoDetails, err := models.GetPerconaSSODetails(ctx, db.Querier)
- if err != nil {
- deps.l.Warnf("Failed to get Percona SSO Details: %+v.", err)
+ if err != nil && !errors.Is(err, models.ErrNotConnectedToPortal) {
+ deps.l.Warnf("Failed to get Percona SSO Details: %s.", err)
}
if err = deps.supervisord.UpdateConfiguration(settings, ssoDetails); err != nil {
- deps.l.Warnf("Failed to update supervisord configuration: %+v.", err)
+ deps.l.Warnf("Failed to update supervisord configuration: %s.", err)
return false
}
@@ -586,9 +593,14 @@ func setup(ctx context.Context, deps *setupDeps) bool {
}
func getQANClient(ctx context.Context, sqlDB *sql.DB, dbName, qanAPIAddr string) *qan.Client {
+ bc := backoff.DefaultConfig
+ bc.MaxDelay = time.Second
+
opts := []grpc.DialOption{
grpc.WithTransportCredentials(insecure.NewCredentials()),
- grpc.WithBackoffMaxDelay(time.Second), //nolint:staticcheck
+ grpc.WithConnectParams(grpc.ConnectParams{
+ Backoff: bc,
+ }),
grpc.WithUserAgent("pmm-managed/" + version.Version),
grpc.WithDefaultCallOptions(grpc.MaxCallRecvMsgSize(gRPCMessageMaxSize)),
}
@@ -658,9 +670,9 @@ func main() { //nolint:cyclop,maintidx
kingpin.Version(version.FullInfo())
kingpin.HelpFlag.Short('h')
- victoriaMetricsURLF := kingpin.Flag("victoriametrics-url", "VictoriaMetrics base URL").
- Default("http://127.0.0.1:9090/prometheus/").String()
- victoriaMetricsVMAlertURLF := kingpin.Flag("victoriametrics-vmalert-url", "VictoriaMetrics VMAlert base URL").
+ victoriaMetricsURLF := kingpin.Flag("victoriametrics-url", "VictoriaMetrics base URL").Envar("PMM_VM_URL").
+ Default(models.VMBaseURL).String()
+ victoriaMetricsVMAlertURLF := kingpin.Flag("victoriametrics-vmalert-url", "VictoriaMetrics VMAlert base URL").Envar("PMM_VM_ALERT_URL").
Default("http://127.0.0.1:8880/").String()
victoriaMetricsConfigF := kingpin.Flag("victoriametrics-config", "VictoriaMetrics scrape configuration file path").
Default("/etc/victoriametrics-promscrape.yml").String()
@@ -740,6 +752,7 @@ func main() { //nolint:cyclop,maintidx
*postgresSSLModeF = models.VerifyCaSSLMode
}
ds := cfg.Config.Services.Telemetry.DataSources
+
pmmdb := ds.PmmDBSelect
pmmdb.Credentials.Username = *postgresDBUsernameF
pmmdb.Credentials.Password = *postgresDBPasswordF
@@ -760,6 +773,15 @@ func main() { //nolint:cyclop,maintidx
qanDB := ds.QanDBSelect
qanDB.DSN = clickhouseDSN
+ ds.VM.Address = *victoriaMetricsURLF
+
+ vmParams, err := models.NewVictoriaMetricsParams(
+ models.BasePrometheusConfigPath,
+ *victoriaMetricsURLF)
+ if err != nil {
+ l.Panicf("cannot load victoriametrics params problem: %+v", err)
+ }
+
setupParams := models.SetupDBParams{
Address: *postgresAddrF,
Name: *postgresDBNameF,
@@ -792,12 +814,7 @@ func main() { //nolint:cyclop,maintidx
cleaner := clean.New(db)
externalRules := vmalert.NewExternalRules()
-
- vmParams, err := models.NewVictoriaMetricsParams(victoriametrics.BasePrometheusConfigPath)
- if err != nil {
- l.Panicf("cannot load victoriametrics params problem: %+v", err)
- }
- vmdb, err := victoriametrics.NewVictoriaMetrics(*victoriaMetricsConfigF, db, *victoriaMetricsURLF, vmParams)
+ vmdb, err := victoriametrics.NewVictoriaMetrics(*victoriaMetricsConfigF, db, vmParams)
if err != nil {
l.Panicf("VictoriaMetrics service problem: %+v", err)
}
@@ -811,7 +828,7 @@ func main() { //nolint:cyclop,maintidx
qanClient := getQANClient(ctx, sqlDB, *postgresDBNameF, *qanAPIAddrF)
- agentsRegistry := agents.NewRegistry(db)
+ agentsRegistry := agents.NewRegistry(db, vmParams)
pbmPITRService := backup.NewPBMPITRService()
backupRemovalService := backup.NewRemovalService(db, pbmPITRService)
backupRetentionService := backup.NewRetentionService(db, backupRemovalService)
@@ -830,7 +847,7 @@ func main() { //nolint:cyclop,maintidx
pmmUpdateCheck := supervisord.NewPMMUpdateChecker(logrus.WithField("component", "supervisord/pmm-update-checker"))
- logs := supervisord.NewLogs(version.FullInfo(), pmmUpdateCheck)
+ logs := supervisord.NewLogs(version.FullInfo(), pmmUpdateCheck, vmParams)
supervisord := supervisord.New(
*supervisordConfigDirF,
@@ -875,7 +892,7 @@ func main() { //nolint:cyclop,maintidx
prom.MustRegister(grafanaClient)
jobsService := agents.NewJobsService(db, agentsRegistry, backupRetentionService)
- agentsStateUpdater := agents.NewStateUpdater(db, agentsRegistry, vmdb)
+ agentsStateUpdater := agents.NewStateUpdater(db, agentsRegistry, vmdb, vmParams)
agentsHandler := agents.NewHandler(db, qanClient, vmdb, agentsRegistry, agentsStateUpdater, jobsService)
actionsService := agents.NewActionsService(qanClient, agentsRegistry)
@@ -890,8 +907,7 @@ func main() { //nolint:cyclop,maintidx
l.Fatalf("Could not create Clickhouse client: %s", err)
}
- checksService := checks.New(db, platformClient, actionsService, alertManager, v1.NewAPI(vmClient), clickhouseClient)
-
+ checksService := checks.New(db, platformClient, actionsService, v1.NewAPI(vmClient), clickhouseClient)
prom.MustRegister(checksService)
alertingService, err := alerting.NewService(db, platformClient, grafanaClient)
@@ -907,6 +923,9 @@ func main() { //nolint:cyclop,maintidx
dbaasClient := dbaas.NewClient(*dbaasControllerAPIAddrF)
compatibilityService := backup.NewCompatibilityService(db, versioner)
backupService := backup.NewService(db, jobsService, agentService, compatibilityService, pbmPITRService)
+ backupMetricsCollector := backup.NewMetricsCollector(db)
+ prom.MustRegister(backupMetricsCollector)
+
schedulerService := scheduler.New(db, backupService)
versionCache := versioncache.New(db, versioner)
diff --git a/managed/cmd/pmm-managed/main_test.go b/managed/cmd/pmm-managed/main_test.go
index 894f272a4d..4ce740f9ef 100644
--- a/managed/cmd/pmm-managed/main_test.go
+++ b/managed/cmd/pmm-managed/main_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -41,6 +41,7 @@ func TestPackages(t *testing.T) {
func TestImports(t *testing.T) {
type constraint struct {
blacklistPrefixes []string
+ whitelistPrefixes []string
}
constraints := make(map[string]constraint)
@@ -76,7 +77,6 @@ func TestImports(t *testing.T) {
// those services should be independent too, but has some common code
// as converters, errors, ...
"github.com/percona/pmm/managed/services/grafana",
- "github.com/percona/pmm/managed/services/inventory",
"github.com/percona/pmm/managed/services/management",
"github.com/percona/pmm/managed/services/server",
"github.com/percona/pmm/managed/services/checks",
@@ -89,6 +89,20 @@ func TestImports(t *testing.T) {
}
}
+ for _, service := range []string{
+ // TODO come up with a new code structure that allows cross-service communication without the need to do tricks.
+ "github.com/percona/pmm/managed/services/inventory",
+ } {
+ constraints[service] = constraint{
+ blacklistPrefixes: []string{
+ "github.com/percona/pmm/managed/services/",
+ },
+ whitelistPrefixes: []string{
+ "github.com/percona/pmm/managed/services/management/common",
+ },
+ }
+ }
+
// validators should not import gRPC stack, including errors
constraints["github.com/percona/pmm/managed/utils/validators"] = constraint{
blacklistPrefixes: []string{
@@ -127,6 +141,18 @@ func TestImports(t *testing.T) {
continue
}
+ // check allowlist
+ var allow bool
+ for _, a := range c.whitelistPrefixes {
+ if strings.HasPrefix(i, a) {
+ allow = true
+ break
+ }
+ }
+ if allow {
+ continue
+ }
+
// check blacklist
if strings.HasPrefix(i, b) {
t.Errorf("Package %q should not import package %q (blacklisted by %q).", path, i, b)
diff --git a/managed/cmd/pmm-managed/maincover_test.go b/managed/cmd/pmm-managed/maincover_test.go
index a1e85dbf87..4f5accd141 100644
--- a/managed/cmd/pmm-managed/maincover_test.go
+++ b/managed/cmd/pmm-managed/maincover_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/data/gen.go b/managed/data/gen.go
index 5f276bc4e9..e0364769c4 100644
--- a/managed/data/gen.go
+++ b/managed/data/gen.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/data/iatemplates/agent_down.yml b/managed/data/iatemplates/agent_down.yml
index e913696f6e..89abeb7a12 100644
--- a/managed/data/iatemplates/agent_down.yml
+++ b/managed/data/iatemplates/agent_down.yml
@@ -8,6 +8,5 @@ templates:
severity: critical
annotations:
description: |-
- PMM agent on node '{{ $labels.node_id }}' cannot be reached. Host may be down.
- summary: PMM agent on node '{{ $labels.node_id }}' cannot be reached. Host may be down.
-
+ PMM agent on node '{{ $labels.node_name }}', node ID '{{ $labels.node_id }}', cannot be reached. Host may be down.
+ summary: PMM agent on node '{{ $labels.node_name }}' cannot be reached. Host may be down.
diff --git a/managed/data/iatemplates/backup_error.yml b/managed/data/iatemplates/backup_error.yml
new file mode 100644
index 0000000000..592c109c9c
--- /dev/null
+++ b/managed/data/iatemplates/backup_error.yml
@@ -0,0 +1,12 @@
+---
+templates:
+ - name: pmm_backup_error
+ version: 1
+ summary: Backup failed (Tech preview)
+ expr: 'pmm_managed_backups_artifacts{status="error"} == bool 1'
+ for: 1m
+ severity: error
+ annotations:
+ description: |-
+ Failed to create a backup artifact '{{ $labels.artifact_name}}' on service '{{ $labels.service_id }}'.
+ summary: Failed to create a backup artifact '{{ $labels.artifact_name}}' on service '{{ $labels.service_id }}'.
diff --git a/managed/models/action_helpers.go b/managed/models/action_helpers.go
index a61f08bdca..761fa84826 100644
--- a/managed/models/action_helpers.go
+++ b/managed/models/action_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/action_helpers_test.go b/managed/models/action_helpers_test.go
index 20270553d8..30009aeb95 100644
--- a/managed/models/action_helpers_test.go
+++ b/managed/models/action_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/action_models.go b/managed/models/action_models.go
index e6bc10876c..451932d8ce 100644
--- a/managed/models/action_models.go
+++ b/managed/models/action_models.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -57,7 +57,7 @@ func (s *ActionResult) AfterFind() error {
return nil
}
-// check interfaces
+// check interfaces.
var (
_ reform.BeforeInserter = (*ActionResult)(nil)
_ reform.BeforeUpdater = (*ActionResult)(nil)
diff --git a/managed/models/agent_helpers.go b/managed/models/agent_helpers.go
index 21df05d004..4d6e65c22e 100644
--- a/managed/models/agent_helpers.go
+++ b/managed/models/agent_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/agent_helpers_test.go b/managed/models/agent_helpers_test.go
index 44c679d846..dd48be34e7 100644
--- a/managed/models/agent_helpers_test.go
+++ b/managed/models/agent_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/agent_model.go b/managed/models/agent_model.go
index 1ae1cb2d22..c7cfc2f5c8 100644
--- a/managed/models/agent_model.go
+++ b/managed/models/agent_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/agent_model_test.go b/managed/models/agent_model_test.go
index 0fa15a86af..fd4eacd881 100644
--- a/managed/models/agent_model_test.go
+++ b/managed/models/agent_model_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/artifact_helpers.go b/managed/models/artifact_helpers.go
index 382d153bf0..ed8a95a0cd 100644
--- a/managed/models/artifact_helpers.go
+++ b/managed/models/artifact_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -36,6 +36,8 @@ type ArtifactFilters struct {
ScheduleID string
// Return only artifacts by specified status.
Status BackupStatus
+ // Filters by folder.
+ Folder *string
}
// FindArtifacts returns artifact list sorted by creation time in DESCENDING order.
@@ -67,6 +69,13 @@ func FindArtifacts(q *reform.Querier, filters ArtifactFilters) ([]*Artifact, err
if filters.Status != "" {
conditions = append(conditions, fmt.Sprintf("status = %s", q.Placeholder(idx)))
args = append(args, filters.Status)
+ idx++
+ }
+
+ if filters.Folder != nil {
+ conditions = append(conditions, fmt.Sprintf("folder = %s", q.Placeholder(idx)))
+ args = append(args, *filters.Folder)
+ // idx++
}
var whereClause string
diff --git a/managed/models/artifact_helpers_test.go b/managed/models/artifact_helpers_test.go
index e459e7c6a7..8d2cc84783 100644
--- a/managed/models/artifact_helpers_test.go
+++ b/managed/models/artifact_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -167,10 +167,23 @@ func TestArtifacts(t *testing.T) {
Mode: models.Snapshot,
}
+ params3 := models.CreateArtifactParams{
+ Name: "backup_name_3",
+ Vendor: "mongodb",
+ LocationID: locationID2,
+ ServiceID: serviceID2,
+ DataModel: models.LogicalDataModel,
+ Status: models.SuccessBackupStatus,
+ Mode: models.Snapshot,
+ Folder: "some_folder",
+ }
+
a1, err := models.CreateArtifact(q, params1)
require.NoError(t, err)
a2, err := models.CreateArtifact(q, params2)
require.NoError(t, err)
+ a3, err := models.CreateArtifact(q, params3)
+ require.NoError(t, err)
actual, err := models.FindArtifacts(q, models.ArtifactFilters{})
require.NoError(t, err)
@@ -188,6 +201,19 @@ func TestArtifacts(t *testing.T) {
assert.Condition(t, found(a1.ID), "The first artifact not found")
assert.Condition(t, found(a2.ID), "The second artifact not found")
+
+ // Check artifacts can be found by folder.
+ actual2, err := models.FindArtifacts(q, models.ArtifactFilters{Folder: &a3.Folder})
+ require.NoError(t, err)
+ assert.Equal(t, []*models.Artifact{a3}, actual2)
+
+ actual3, err := models.FindArtifacts(q, models.ArtifactFilters{})
+ require.NoError(t, err)
+ require.Equal(t, 3, len(actual3))
+
+ for _, a := range actual3 {
+ assert.Contains(t, []models.Artifact{*a1, *a2, *a3}, *a)
+ }
})
t.Run("remove", func(t *testing.T) {
diff --git a/managed/models/artifact_model.go b/managed/models/artifact_model.go
index 6c879d4d24..2ec01b4c6b 100644
--- a/managed/models/artifact_model.go
+++ b/managed/models/artifact_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/check_settings_helper.go b/managed/models/check_settings_helper.go
index ad9d09ac97..d22855ffcf 100644
--- a/managed/models/check_settings_helper.go
+++ b/managed/models/check_settings_helper.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/check_settings_helper_test.go b/managed/models/check_settings_helper_test.go
index 427de8750a..b64de25bd1 100644
--- a/managed/models/check_settings_helper_test.go
+++ b/managed/models/check_settings_helper_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/check_settings_model.go b/managed/models/check_settings_model.go
index 76c6fa62ba..133b6d64a9 100644
--- a/managed/models/check_settings_model.go
+++ b/managed/models/check_settings_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/common_helpers.go b/managed/models/common_helpers.go
index 5e81f7563e..ee79c6a590 100644
--- a/managed/models/common_helpers.go
+++ b/managed/models/common_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/database.go b/managed/models/database.go
index 342a76dc39..4839eedde8 100644
--- a/managed/models/database.go
+++ b/managed/models/database.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -916,6 +916,9 @@ var databaseSchema = [][]string{
ALTER COLUMN comments_parsing_disabled DROP DEFAULT`,
},
85: {
+ `UPDATE services SET cluster = service_name WHERE cluster = ''`,
+ },
+ 86: {
`DROP TABLE IF EXISTS ia_channels`,
`DROP TABLE IF EXISTS ia_rules`,
`ALTER TABLE ia_templates RENAME TO alert_rule_templates`,
diff --git a/managed/models/database_test.go b/managed/models/database_test.go
index 083ab679a6..0f86574b19 100644
--- a/managed/models/database_test.go
+++ b/managed/models/database_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -32,7 +32,7 @@ import (
"github.com/percona/pmm/managed/utils/testdb"
)
-// See https://www.postgresql.org/docs/10/errcodes-appendix.html for error codes
+// See https://www.postgresql.org/docs/10/errcodes-appendix.html for error codes.
func assertUniqueViolation(t *testing.T, err error, constraint string) {
t.Helper()
diff --git a/managed/models/delimiter.go b/managed/models/delimiter.go
index 9e96c707ff..23d9e0025b 100644
--- a/managed/models/delimiter.go
+++ b/managed/models/delimiter.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/dsn_helpers.go b/managed/models/dsn_helpers.go
index 34d4c722b2..a702e6efac 100644
--- a/managed/models/dsn_helpers.go
+++ b/managed/models/dsn_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/dsn_helpers_test.go b/managed/models/dsn_helpers_test.go
index 712d3bc24c..668f8863ce 100644
--- a/managed/models/dsn_helpers_test.go
+++ b/managed/models/dsn_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/errors.go b/managed/models/errors.go
index a0c1551e08..f97b89692c 100644
--- a/managed/models/errors.go
+++ b/managed/models/errors.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/job_helpers.go b/managed/models/job_helpers.go
index 1762c7b34f..08327e2cd9 100644
--- a/managed/models/job_helpers.go
+++ b/managed/models/job_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/job_helpers_test.go b/managed/models/job_helpers_test.go
index 9c2cf9793d..c554b04e7a 100644
--- a/managed/models/job_helpers_test.go
+++ b/managed/models/job_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/job_models.go b/managed/models/job_models.go
index 43cd975d84..e34d404a93 100644
--- a/managed/models/job_models.go
+++ b/managed/models/job_models.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/kubernetes_helpers.go b/managed/models/kubernetes_helpers.go
index 7c2a2d9447..8128803ddd 100644
--- a/managed/models/kubernetes_helpers.go
+++ b/managed/models/kubernetes_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -117,7 +117,7 @@ func CreateKubernetesCluster(q *reform.Querier, params *CreateKubernetesClusterP
return row, nil
}
-// ChangeKubernetesClusterToReady changes k8s cluster to ready state once provisioning is finished
+// ChangeKubernetesClusterToReady changes k8s cluster to ready state once provisioning is finished.
func ChangeKubernetesClusterToReady(q *reform.Querier, name string) error {
c, err := FindKubernetesClusterByName(q, name)
if err != nil {
diff --git a/managed/models/kubernetes_helpers_test.go b/managed/models/kubernetes_helpers_test.go
index 1b8eb72600..6b602ba728 100644
--- a/managed/models/kubernetes_helpers_test.go
+++ b/managed/models/kubernetes_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/kubernetes_models.go b/managed/models/kubernetes_models.go
index 1fa98726f4..aef490cd3e 100644
--- a/managed/models/kubernetes_models.go
+++ b/managed/models/kubernetes_models.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -24,7 +24,7 @@ import (
//go:generate ../../bin/reform
-// Component stores info about DBaaS Component
+// Component stores info about DBaaS Component.
type Component struct {
DisabledVersions []string
DefaultVersion string
diff --git a/managed/models/location_helpers.go b/managed/models/location_helpers.go
index de7da55a21..8172d25a0a 100644
--- a/managed/models/location_helpers.go
+++ b/managed/models/location_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/location_helpers_test.go b/managed/models/location_helpers_test.go
index 032240a1d1..4ad3df1796 100644
--- a/managed/models/location_helpers_test.go
+++ b/managed/models/location_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/location_model.go b/managed/models/location_model.go
index ddde641b1b..5272b5c624 100644
--- a/managed/models/location_model.go
+++ b/managed/models/location_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -27,7 +27,7 @@ import (
// BackupLocationType represents BackupLocation type as stored in database.
type BackupLocationType string
-// BackupLocation types. Same as in agent/runner/jobs/backup_location.go
+// BackupLocation types. Same as in agent/runner/jobs/backup_location.go.
const (
S3BackupLocationType BackupLocationType = "s3"
FilesystemBackupLocationType BackupLocationType = "filesystem"
diff --git a/managed/models/models.go b/managed/models/models.go
index b135a82f01..c92479e1b0 100644
--- a/managed/models/models.go
+++ b/managed/models/models.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/models_json_test.go b/managed/models/models_json_test.go
index 80e5c7a6d9..ad35313dc4 100644
--- a/managed/models/models_json_test.go
+++ b/managed/models/models_json_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/models_test.go b/managed/models/models_test.go
index ed5a5a4f92..4de96c5767 100644
--- a/managed/models/models_test.go
+++ b/managed/models/models_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/node_helpers.go b/managed/models/node_helpers.go
index 638273634a..34c743bab5 100644
--- a/managed/models/node_helpers.go
+++ b/managed/models/node_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/node_helpers_test.go b/managed/models/node_helpers_test.go
index 2f858d40f6..6e3ac6b770 100644
--- a/managed/models/node_helpers_test.go
+++ b/managed/models/node_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -132,7 +132,7 @@ func TestNodeHelpers(t *testing.T) {
})
assert.NoError(t, err)
- structs, err := q.SelectAllFrom(models.NodeTable, "WHERE machine_id = $1 ORDER BY node_id DESC", machineID)
+ structs, err := q.SelectAllFrom(models.NodeTable, "WHERE machine_id = $1 ORDER BY node_id", machineID)
require.NoError(t, err)
require.Len(t, structs, 2)
expected := &models.Node{
diff --git a/managed/models/node_model.go b/managed/models/node_model.go
index c6ebdf104a..3406071eb5 100644
--- a/managed/models/node_model.go
+++ b/managed/models/node_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -134,7 +134,7 @@ func (s *Node) UnifiedLabels() (map[string]string, error) {
return res, nil
}
-// check interfaces
+// check interfaces.
var (
_ reform.BeforeInserter = (*Node)(nil)
_ reform.BeforeUpdater = (*Node)(nil)
diff --git a/managed/models/node_model_test.go b/managed/models/node_model_test.go
index 6bda8f5b0e..cee4269105 100644
--- a/managed/models/node_model_test.go
+++ b/managed/models/node_model_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/percona_sso_model.go b/managed/models/percona_sso_model.go
index 15629ff959..afa5009e84 100644
--- a/managed/models/percona_sso_model.go
+++ b/managed/models/percona_sso_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/percona_sso_model_helpers.go b/managed/models/percona_sso_model_helpers.go
index e91935b49b..55cda53440 100644
--- a/managed/models/percona_sso_model_helpers.go
+++ b/managed/models/percona_sso_model_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/percona_sso_model_helpers_test.go b/managed/models/percona_sso_model_helpers_test.go
index d4386350af..23f59c2d7d 100644
--- a/managed/models/percona_sso_model_helpers_test.go
+++ b/managed/models/percona_sso_model_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/postgres.go b/managed/models/postgres.go
index 641abefea0..72b6dfc906 100644
--- a/managed/models/postgres.go
+++ b/managed/models/postgres.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/postgresql_version.go b/managed/models/postgresql_version.go
index a5e6cb53eb..47136278b0 100644
--- a/managed/models/postgresql_version.go
+++ b/managed/models/postgresql_version.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -24,7 +24,7 @@ import (
"gopkg.in/reform.v1"
)
-// regexps to extract version numbers from the `SELECT version()` output
+// regexps to extract version numbers from the `SELECT version()` output.
var (
postgresDBRegexp = regexp.MustCompile(`PostgreSQL (\d+\.?\d+)`)
)
diff --git a/managed/models/postgresql_version_test.go b/managed/models/postgresql_version_test.go
index 5a676118ca..98828bba84 100644
--- a/managed/models/postgresql_version_test.go
+++ b/managed/models/postgresql_version_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/restore_history_helpers.go b/managed/models/restore_history_helpers.go
index 8680f97341..65bef9c0d2 100644
--- a/managed/models/restore_history_helpers.go
+++ b/managed/models/restore_history_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/restore_history_helpers_test.go b/managed/models/restore_history_helpers_test.go
index db837c1644..1621fe51d8 100644
--- a/managed/models/restore_history_helpers_test.go
+++ b/managed/models/restore_history_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/restore_history_model.go b/managed/models/restore_history_model.go
index fba2d166a4..ccfdb1a4eb 100644
--- a/managed/models/restore_history_model.go
+++ b/managed/models/restore_history_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/role_helpers.go b/managed/models/role_helpers.go
index 9abcd2ab21..da1c25057b 100644
--- a/managed/models/role_helpers.go
+++ b/managed/models/role_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/role_helpers_test.go b/managed/models/role_helpers_test.go
index 17394c4ff6..9121665095 100644
--- a/managed/models/role_helpers_test.go
+++ b/managed/models/role_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/role_model.go b/managed/models/role_model.go
index 964098b9c4..16d653e9f3 100644
--- a/managed/models/role_model.go
+++ b/managed/models/role_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/scheduled_task_models.go b/managed/models/scheduled_task_models.go
index 4e928f9f84..b4419531f1 100644
--- a/managed/models/scheduled_task_models.go
+++ b/managed/models/scheduled_task_models.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/scheduled_tasks_helpers.go b/managed/models/scheduled_tasks_helpers.go
index f7c5f51bf0..be58f5eaf5 100644
--- a/managed/models/scheduled_tasks_helpers.go
+++ b/managed/models/scheduled_tasks_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -55,6 +55,7 @@ type ScheduledTasksFilter struct {
LocationID string
Mode BackupMode
Name string
+ Folder *string
}
// FindScheduledTasks returns all scheduled tasks satisfying filter.
@@ -110,6 +111,12 @@ func FindScheduledTasks(q *reform.Querier, filters ScheduledTasksFilter) ([]*Sch
crossJoin = true
andConds = append(andConds, "value ->> 'name' = "+q.Placeholder(idx))
args = append(args, filters.Name)
+ idx++
+ }
+ if filters.Folder != nil {
+ crossJoin = true
+ andConds = append(andConds, "value ->> 'folder' = "+q.Placeholder(idx))
+ args = append(args, *filters.Folder)
// idx++
}
@@ -367,6 +374,15 @@ func (s *ScheduledTask) LocationID() (string, error) {
return data.LocationID, nil
}
+// ServiceID returns task service ID.
+func (s *ScheduledTask) ServiceID() (string, error) {
+ data, err := s.CommonBackupData()
+ if err != nil {
+ return "", err
+ }
+ return data.ServiceID, nil
+}
+
func (s *ScheduledTask) CommonBackupData() (*CommonBackupTaskData, error) {
if s.Data != nil {
switch s.Type {
diff --git a/managed/models/scheduled_tasks_helpers_test.go b/managed/models/scheduled_tasks_helpers_test.go
index 50a1f2b555..c890838f9e 100644
--- a/managed/models/scheduled_tasks_helpers_test.go
+++ b/managed/models/scheduled_tasks_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/service_helpers.go b/managed/models/service_helpers.go
index a2b04f9336..257fae1f61 100644
--- a/managed/models/service_helpers.go
+++ b/managed/models/service_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -402,6 +402,51 @@ func ValidateServiceType(serviceType ServiceType) error {
}
}
+// ChangeStandardLabelsParams contains parameters for changing standard labels for a service.
+type ChangeStandardLabelsParams struct {
+ ServiceID string
+ Cluster *string
+ Environment *string
+ ReplicationSet *string
+ ExternalGroup *string
+}
+
+// ChangeStandardLabels changes standard labels for a service.
+func ChangeStandardLabels(q *reform.Querier, serviceID string, labels ServiceStandardLabelsParams) error {
+ s, err := FindServiceByID(q, serviceID)
+ if err != nil {
+ return err
+ }
+
+ columns := []string{}
+
+ if labels.Cluster != nil {
+ columns = append(columns, "cluster")
+ s.Cluster = *labels.Cluster
+ }
+
+ if labels.Environment != nil {
+ columns = append(columns, "environment")
+ s.Environment = *labels.Environment
+ }
+
+ if labels.ReplicationSet != nil {
+ columns = append(columns, "replication_set")
+ s.ReplicationSet = *labels.ReplicationSet
+ }
+
+ if labels.ExternalGroup != nil {
+ columns = append(columns, "external_group")
+ s.ExternalGroup = *labels.ExternalGroup
+ }
+
+ if err = q.UpdateColumns(s, columns...); err != nil {
+ return err
+ }
+
+ return nil
+}
+
func initSoftwareVersions(q *reform.Querier, serviceID string, serviceType ServiceType) error {
switch serviceType {
case MySQLServiceType:
diff --git a/managed/models/service_helpers_test.go b/managed/models/service_helpers_test.go
index 140497e11a..47d4dc317c 100644
--- a/managed/models/service_helpers_test.go
+++ b/managed/models/service_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -158,10 +158,11 @@ func TestServiceHelpers(t *testing.T) {
services, err = models.FindServices(q, models.ServiceFilters{NodeID: "N1"})
assert.NoError(t, err)
assert.Equal(t, 3, len(services))
- assert.Equal(t, services, []*models.Service{{
+ assert.Equal(t, []*models.Service{{
ServiceID: "S1",
ServiceType: models.MongoDBServiceType,
ServiceName: "Service without Agents",
+ Cluster: "Service without Agents",
NodeID: "N1",
Address: pointer.ToString("127.0.0.1"),
Port: pointer.ToUint16OrNil(27017),
@@ -171,6 +172,7 @@ func TestServiceHelpers(t *testing.T) {
ServiceID: "S2",
ServiceType: models.MySQLServiceType,
ServiceName: "Service with Agents",
+ Cluster: "Service with Agents",
NodeID: "N1",
Address: pointer.ToString("127.0.0.1"),
Port: pointer.ToUint16OrNil(3306),
@@ -180,35 +182,38 @@ func TestServiceHelpers(t *testing.T) {
ServiceID: "S5",
ServiceType: models.ProxySQLServiceType,
ServiceName: "Fifth service",
+ Cluster: "Fifth service",
NodeID: "N1",
Address: pointer.ToString("127.0.0.1"),
Port: pointer.ToUint16OrNil(6032),
CreatedAt: now,
UpdatedAt: now,
- }})
+ }}, services)
services, err = models.FindServices(q, models.ServiceFilters{NodeID: "N1", ServiceType: pointerToServiceType(models.MySQLServiceType)})
assert.NoError(t, err)
assert.Equal(t, 1, len(services))
- assert.Equal(t, services, []*models.Service{{
+ assert.Equal(t, []*models.Service{{
ServiceID: "S2",
ServiceType: models.MySQLServiceType,
ServiceName: "Service with Agents",
+ Cluster: "Service with Agents",
NodeID: "N1",
Address: pointer.ToString("127.0.0.1"),
Port: pointer.ToUint16OrNil(3306),
CreatedAt: now,
UpdatedAt: now,
- }})
+ }}, services)
services, err = models.FindServices(q, models.ServiceFilters{NodeID: "N2", ServiceType: pointerToServiceType(models.ExternalServiceType)})
assert.NoError(t, err)
assert.Equal(t, 2, len(services))
- assert.Equal(t, services, []*models.Service{
+ assert.Equal(t, []*models.Service{
{
ServiceID: "S4",
ServiceType: models.ExternalServiceType,
ServiceName: "Fourth service",
+ Cluster: "Fourth service",
ExternalGroup: "external",
NodeID: "N2",
CreatedAt: now,
@@ -218,6 +223,7 @@ func TestServiceHelpers(t *testing.T) {
ServiceID: "S7",
ServiceType: models.ExternalServiceType,
ServiceName: "Seventh service",
+ Cluster: "Seventh service",
NodeID: "N2",
Address: pointer.ToString("127.0.0.1"),
Port: pointer.ToUint16OrNil(6379),
@@ -225,47 +231,50 @@ func TestServiceHelpers(t *testing.T) {
CreatedAt: now,
UpdatedAt: now,
},
- })
+ }, services)
services, err = models.FindServices(q, models.ServiceFilters{NodeID: "N2", ServiceType: pointerToServiceType(models.ProxySQLServiceType)})
assert.NoError(t, err)
assert.Equal(t, 1, len(services))
- assert.Equal(t, services, []*models.Service{{
+ assert.Equal(t, []*models.Service{{
ServiceID: "S6",
ServiceType: models.ProxySQLServiceType,
ServiceName: "Sixth service",
+ Cluster: "Sixth service",
Socket: pointer.ToStringOrNil("/tmp/proxysql_admin.sock"),
NodeID: "N2",
CreatedAt: now,
UpdatedAt: now,
- }})
+ }}, services)
services, err = models.FindServices(q, models.ServiceFilters{ExternalGroup: "redis"})
assert.NoError(t, err)
assert.Equal(t, 1, len(services))
- assert.Equal(t, services, []*models.Service{{
+ assert.Equal(t, []*models.Service{{
ServiceID: "S7",
ServiceType: models.ExternalServiceType,
ServiceName: "Seventh service",
+ Cluster: "Seventh service",
NodeID: "N2",
Address: pointer.ToString("127.0.0.1"),
Port: pointer.ToUint16OrNil(6379),
ExternalGroup: "redis",
CreatedAt: now,
UpdatedAt: now,
- }})
+ }}, services)
services, err = models.FindServices(q, models.ServiceFilters{NodeID: "N2", ServiceType: pointerToServiceType(models.HAProxyServiceType)})
assert.NoError(t, err)
assert.Equal(t, 1, len(services))
- assert.Equal(t, services, []*models.Service{{
+ assert.Equal(t, []*models.Service{{
ServiceID: "S8",
ServiceType: models.HAProxyServiceType,
ServiceName: "Eighth service",
+ Cluster: "Eighth service",
NodeID: "N2",
CreatedAt: now,
UpdatedAt: now,
- }})
+ }}, services)
})
t.Run("FindActiveServiceTypes", func(t *testing.T) {
@@ -442,6 +451,36 @@ func TestServiceHelpers(t *testing.T) {
assert.ElementsMatch(t, []*models.Service{s1, s2}, services)
})
+ t.Run("Change standard labels", func(t *testing.T) {
+ q, teardown := setup(t)
+ defer teardown(t)
+ s, err := models.AddNewService(q, models.ExternalServiceType, &models.AddDBMSServiceParams{
+ ServiceName: "mongors1",
+ NodeID: "N1",
+ Cluster: "cluster0",
+ ExternalGroup: "ext",
+ Address: pointer.ToString("127.0.0.1"),
+ Port: pointer.ToUint16OrNil(27017),
+ })
+ require.NoError(t, err)
+
+ err = models.ChangeStandardLabels(q, s.ServiceID, models.ServiceStandardLabelsParams{
+ Cluster: pointer.ToString("cluster"),
+ Environment: pointer.ToString("env"),
+ ReplicationSet: pointer.ToString("rs"),
+ ExternalGroup: pointer.ToString("external"),
+ })
+ require.NoError(t, err)
+
+ ns, err := models.FindServiceByID(q, s.ServiceID)
+ require.NoError(t, err)
+
+ assert.Equal(t, ns.Cluster, "cluster")
+ assert.Equal(t, ns.Environment, "env")
+ assert.Equal(t, ns.ReplicationSet, "rs")
+ assert.Equal(t, ns.ExternalGroup, "external")
+ })
+
t.Run("Software versions record created when adding a service", func(t *testing.T) {
q, teardown := setup(t)
defer teardown(t)
diff --git a/managed/models/service_model.go b/managed/models/service_model.go
index 55e326826b..04c7484156 100644
--- a/managed/models/service_model.go
+++ b/managed/models/service_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -27,6 +27,13 @@ import (
// pmm-managed's PostgreSQL, qan-api's ClickHouse, and VictoriaMetrics.
type ServiceType string
+type ServiceStandardLabelsParams struct {
+ Cluster *string
+ Environment *string
+ ReplicationSet *string
+ ExternalGroup *string
+}
+
// Service types (in the same order as in services.proto).
const (
MySQLServiceType ServiceType = "mysql"
@@ -67,6 +74,9 @@ func (s *Service) BeforeInsert() error {
if len(s.CustomLabels) == 0 {
s.CustomLabels = nil
}
+ if s.Cluster == "" {
+ s.Cluster = s.ServiceName
+ }
return nil
}
@@ -76,6 +86,9 @@ func (s *Service) BeforeUpdate() error {
if len(s.CustomLabels) == 0 {
s.CustomLabels = nil
}
+ if s.Cluster == "" {
+ s.Cluster = s.ServiceName
+ }
return nil
}
@@ -125,7 +138,7 @@ func (s *Service) UnifiedLabels() (map[string]string, error) {
return res, nil
}
-// check interfaces
+// check interfaces.
var (
_ reform.BeforeInserter = (*Service)(nil)
_ reform.BeforeUpdater = (*Service)(nil)
diff --git a/managed/models/service_model_test.go b/managed/models/service_model_test.go
index 7493c5fe13..a26dcce51a 100644
--- a/managed/models/service_model_test.go
+++ b/managed/models/service_model_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/settings.go b/managed/models/settings.go
index 30087b1469..1327128ca4 100644
--- a/managed/models/settings.go
+++ b/managed/models/settings.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/settings_helpers.go b/managed/models/settings_helpers.go
index 5c83332368..c48968ddf1 100644
--- a/managed/models/settings_helpers.go
+++ b/managed/models/settings_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/settings_helpers_test.go b/managed/models/settings_helpers_test.go
index a810559fda..0474d3927b 100644
--- a/managed/models/settings_helpers_test.go
+++ b/managed/models/settings_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/software_version.go b/managed/models/software_version.go
index ac9410ff97..0fc5d38b37 100644
--- a/managed/models/software_version.go
+++ b/managed/models/software_version.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/software_version_helpers.go b/managed/models/software_version_helpers.go
index 9d49e33b4c..853ae749df 100644
--- a/managed/models/software_version_helpers.go
+++ b/managed/models/software_version_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/software_version_helpers_test.go b/managed/models/software_version_helpers_test.go
index a0ea43e75f..24b7c32a17 100644
--- a/managed/models/software_version_helpers_test.go
+++ b/managed/models/software_version_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/template_helpers.go b/managed/models/template_helpers.go
index e89f749f2d..7c0ca1ee57 100644
--- a/managed/models/template_helpers.go
+++ b/managed/models/template_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -44,17 +44,15 @@ func checkUniqueTemplateName(q *reform.Querier, name string) error {
}
// FindTemplates returns saved notification rule templates.
-func FindTemplates(q *reform.Querier) ([]Template, error) {
+func FindTemplates(q *reform.Querier) ([]*Template, error) {
structs, err := q.SelectAllFrom(TemplateTable, "")
if err != nil {
return nil, errors.Wrap(err, "failed to select notification rule templates")
}
- templates := make([]Template, len(structs))
+ templates := make([]*Template, len(structs))
for i, s := range structs {
- c := s.(*Template) //nolint:forcetypeassert
-
- templates[i] = *c
+ templates[i] = s.(*Template) //nolint:forcetypeassert
}
return templates, nil
@@ -81,7 +79,6 @@ func FindTemplateByName(q *reform.Querier, name string) (*Template, error) {
// CreateTemplateParams are params for creating new rule template.
type CreateTemplateParams struct {
Template *alert.Template
- Yaml string
Source Source
}
@@ -92,33 +89,13 @@ func CreateTemplate(q *reform.Querier, params *CreateTemplateParams) (*Template,
return nil, status.Errorf(codes.InvalidArgument, "Invalid rule template: %v.", err)
}
- if err := checkUniqueTemplateName(q, params.Template.Name); err != nil {
+ if err := checkUniqueTemplateName(q, template.Name); err != nil {
return nil, err
}
- p, err := ConvertParamsDefinitions(params.Template.Params)
+ row, err := ConvertTemplate(template, params.Source)
if err != nil {
- return nil, status.Errorf(codes.InvalidArgument, "Invalid rule template parameters: %v.", err)
- }
-
- row := &Template{
- Name: template.Name,
- Version: template.Version,
- Summary: template.Summary,
- Expr: template.Expr,
- Params: p,
- For: time.Duration(template.For),
- Severity: Severity(template.Severity),
- Source: params.Source,
- Yaml: params.Yaml,
- }
-
- if err := row.SetLabels(template.Labels); err != nil {
- return nil, err
- }
-
- if err := row.SetAnnotations(template.Annotations); err != nil {
- return nil, err
+ return nil, status.Errorf(codes.InvalidArgument, "Failed to convert template: %v.", err)
}
if err = q.Insert(row); err != nil {
@@ -132,7 +109,6 @@ func CreateTemplate(q *reform.Querier, params *CreateTemplateParams) (*Template,
type ChangeTemplateParams struct {
Template *alert.Template
Name string
- Yaml string
}
// ChangeTemplate updates existing rule template.
@@ -151,6 +127,11 @@ func ChangeTemplate(q *reform.Querier, params *ChangeTemplateParams) (*Template,
return nil, status.Errorf(codes.InvalidArgument, "Invalid rule template: %v.", err)
}
+ yaml, err := alert.ToYAML([]alert.Template{*template})
+ if err != nil {
+ return nil, errors.WithStack(err)
+ }
+
p, err := ConvertParamsDefinitions(params.Template.Params)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "Invalid rule template parameters: %v.", err)
@@ -163,7 +144,7 @@ func ChangeTemplate(q *reform.Querier, params *ChangeTemplateParams) (*Template,
row.Params = p
row.For = time.Duration(template.For)
row.Severity = Severity(template.Severity)
- row.Yaml = params.Yaml
+ row.Yaml = yaml
if err = row.SetLabels(template.Labels); err != nil {
return nil, err
@@ -193,6 +174,40 @@ func RemoveTemplate(q *reform.Querier, name string) error {
return nil
}
+func ConvertTemplate(template *alert.Template, source Source) (*Template, error) {
+ p, err := ConvertParamsDefinitions(template.Params)
+ if err != nil {
+ return nil, errors.Errorf("invalid rule template parameters: %v.", err)
+ }
+
+ yaml, err := alert.ToYAML([]alert.Template{*template})
+ if err != nil {
+ return nil, errors.WithStack(err)
+ }
+
+ res := &Template{
+ Name: template.Name,
+ Version: template.Version,
+ Summary: template.Summary,
+ Expr: template.Expr,
+ Params: p,
+ For: time.Duration(template.For),
+ Severity: Severity(template.Severity),
+ Source: source,
+ Yaml: yaml,
+ }
+
+ if err := res.SetLabels(template.Labels); err != nil {
+ return nil, err
+ }
+
+ if err := res.SetAnnotations(template.Annotations); err != nil {
+ return nil, err
+ }
+
+ return res, nil
+}
+
// ConvertParamsDefinitions converts parameters definitions to the model.
func ConvertParamsDefinitions(params []alert.Parameter) (AlertExprParamsDefinitions, error) {
res := make(AlertExprParamsDefinitions, 0, len(params))
@@ -200,7 +215,7 @@ func ConvertParamsDefinitions(params []alert.Parameter) (AlertExprParamsDefiniti
p := AlertExprParamDefinition{
Name: param.Name,
Summary: param.Summary,
- Unit: string(param.Unit),
+ Unit: ParamUnit(param.Unit),
Type: ParamType(param.Type),
}
diff --git a/managed/models/template_helpers_test.go b/managed/models/template_helpers_test.go
index 1b5f5b2508..4394cf8cce 100644
--- a/managed/models/template_helpers_test.go
+++ b/managed/models/template_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -60,7 +60,7 @@ func TestRuleTemplates(t *testing.T) {
models.AlertExprParamsDefinitions{{
Name: params.Template.Params[0].Name,
Summary: params.Template.Params[0].Summary,
- Unit: string(params.Template.Params[0].Unit),
+ Unit: models.ParamUnit(params.Template.Params[0].Unit),
Type: models.Float,
FloatParam: &models.FloatParam{
Default: pointer.ToFloat64(params.Template.Params[0].Value.(float64)),
@@ -110,7 +110,7 @@ func TestRuleTemplates(t *testing.T) {
models.AlertExprParamsDefinitions{{
Name: updateParams.Template.Params[0].Name,
Summary: updateParams.Template.Params[0].Summary,
- Unit: string(updateParams.Template.Params[0].Unit),
+ Unit: models.ParamUnit(updateParams.Template.Params[0].Unit),
Type: models.Float,
FloatParam: &models.FloatParam{
Default: pointer.ToFloat64(updateParams.Template.Params[0].Value.(float64)),
diff --git a/managed/models/template_model.go b/managed/models/template_model.go
index 2ecb5a656b..fc1794f6a5 100644
--- a/managed/models/template_model.go
+++ b/managed/models/template_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -112,7 +112,7 @@ func (p *AlertExprParamsDefinitions) Scan(src interface{}) error { return jsonSc
type AlertExprParamDefinition struct {
Name string `json:"name"`
Summary string `json:"summary"`
- Unit string `json:"unit"`
+ Unit ParamUnit `json:"unit"`
Type ParamType `json:"type"`
FloatParam *FloatParam `json:"float_param"`
@@ -130,6 +130,15 @@ const (
String = ParamType("string")
)
+// ParamUnit parameter unit.
+type ParamUnit string
+
+// Available parameter units.
+const (
+ Percent = ParamUnit("%")
+ Seconds = ParamUnit("s")
+)
+
// BoolParam represents boolean template parameter.
type BoolParam struct {
Default *bool `json:"default,omitempty"`
diff --git a/managed/models/user_flags_helpers.go b/managed/models/user_flags_helpers.go
index 7d7b9fc969..20f7faea2b 100644
--- a/managed/models/user_flags_helpers.go
+++ b/managed/models/user_flags_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/user_flags_model.go b/managed/models/user_flags_model.go
index 8876c9b994..5f7e8cff1e 100644
--- a/managed/models/user_flags_model.go
+++ b/managed/models/user_flags_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/user_roles_helpers.go b/managed/models/user_roles_helpers.go
index 8bdbc6aa63..47c861f477 100644
--- a/managed/models/user_roles_helpers.go
+++ b/managed/models/user_roles_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/user_roles_model.go b/managed/models/user_roles_model.go
index 7ba870216d..ca8fa2c4d3 100644
--- a/managed/models/user_roles_model.go
+++ b/managed/models/user_roles_model.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/models/victoriametrics.go b/managed/models/victoriametrics_params.go
similarity index 71%
rename from managed/models/victoriametrics.go
rename to managed/models/victoriametrics_params.go
index d8b07caf27..14a86a5d41 100644
--- a/managed/models/victoriametrics.go
+++ b/managed/models/victoriametrics_params.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -16,25 +16,45 @@
package models
import (
+ "net/url"
"os"
+ "strings"
config "github.com/percona/promconfig"
"github.com/pkg/errors"
"gopkg.in/yaml.v3"
)
+const (
+ // BasePrometheusConfigPath - basic path with prometheus config,
+ // that user can mount to container.
+ BasePrometheusConfigPath = "/srv/prometheus/prometheus.base.yml"
+ VMBaseURL = "http://127.0.0.1:9090/prometheus/"
+)
+
// VictoriaMetricsParams - defines flags and settings for victoriametrics.
type VictoriaMetricsParams struct {
// VMAlertFlags additional flags for VMAlert.
VMAlertFlags []string
// BaseConfigPath defines path for basic prometheus config.
BaseConfigPath string
+ // url defines url of Victoria Metrics
+ url *url.URL
}
// NewVictoriaMetricsParams - returns configuration params for VictoriaMetrics.
-func NewVictoriaMetricsParams(basePath string) (*VictoriaMetricsParams, error) {
+func NewVictoriaMetricsParams(basePath string, vmURL string) (*VictoriaMetricsParams, error) {
+ if !strings.HasSuffix(vmURL, "/") {
+ vmURL += "/"
+ }
+
+ URL, err := url.Parse(vmURL)
+ if err != nil {
+ return nil, err
+ }
vmp := &VictoriaMetricsParams{
BaseConfigPath: basePath,
+ url: URL,
}
if err := vmp.UpdateParams(); err != nil {
return vmp, err
@@ -59,7 +79,7 @@ func (vmp *VictoriaMetricsParams) loadVMAlertParams() error {
if !os.IsNotExist(err) {
return errors.Wrap(err, "cannot read baseConfigPath for VMAlertParams")
}
- // fast return if users configuration doesn't exists with path
+ // fast return if users configuration doesn't exist with path
// /srv/prometheus/prometheus.base.yml,
// its maybe mounted into container by user.
return nil
@@ -79,3 +99,18 @@ func (vmp *VictoriaMetricsParams) loadVMAlertParams() error {
return nil
}
+
+func (vmp *VictoriaMetricsParams) ExternalVM() bool {
+ return vmp.url.Hostname() != "127.0.0.1"
+}
+
+func (vmp *VictoriaMetricsParams) URL() string {
+ return vmp.url.String()
+}
+
+func (vmp *VictoriaMetricsParams) URLFor(path string) (*url.URL, error) {
+ if path == "" {
+ return vmp.url, nil
+ }
+ return vmp.url.Parse(path)
+}
diff --git a/managed/models/victoriametrics_test.go b/managed/models/victoriametrics_params_test.go
similarity index 60%
rename from managed/models/victoriametrics_test.go
rename to managed/models/victoriametrics_params_test.go
index 02ab59b036..9f673c7518 100644
--- a/managed/models/victoriametrics_test.go
+++ b/managed/models/victoriametrics_params_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -18,17 +18,48 @@ package models
import (
"testing"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestVictoriaMetricsParams(t *testing.T) {
t.Run("read non exist baseConfigFile", func(t *testing.T) {
- _, err := NewVictoriaMetricsParams("nonExistConfigFile.yml")
+ _, err := NewVictoriaMetricsParams("nonExistConfigFile.yml", VMBaseURL)
require.NoError(t, err)
})
t.Run("check params for VMAlert", func(t *testing.T) {
- vmp, err := NewVictoriaMetricsParams("../testdata/victoriametrics/prometheus.external.alerts.yml")
+ vmp, err := NewVictoriaMetricsParams("../testdata/victoriametrics/prometheus.external.alerts.yml", VMBaseURL)
require.NoError(t, err)
require.Equal(t, []string{"--rule=/srv/external_rules/rul1.yml", "--rule=/srv/external_rules/rule2.yml", "--evaluationInterval=10s"}, vmp.VMAlertFlags)
})
+ t.Run("check external VM", func(t *testing.T) {
+ tests := []struct {
+ url string
+ want bool
+ }{
+ {
+ "http://127.0.0.1:9090/prometheus",
+ false,
+ },
+ {
+ "http://127.0.0.1:9090/prometheus/",
+ false,
+ },
+ {
+ "http://victoriametrics:8428/",
+ true,
+ },
+ {
+ "https://example.com:9090/",
+ true,
+ },
+ }
+ for _, tt := range tests {
+ t.Run(tt.url, func(t *testing.T) {
+ vmp, err := NewVictoriaMetricsParams(BasePrometheusConfigPath, tt.url)
+ require.NoError(t, err)
+ assert.Equalf(t, tt.want, vmp.ExternalVM(), "ExternalVM()")
+ })
+ }
+ })
}
diff --git a/managed/services/agents/actions.go b/managed/services/agents/actions.go
index d8a206b4e4..52a1097d8a 100644
--- a/managed/services/agents/actions.go
+++ b/managed/services/agents/actions.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -66,7 +66,7 @@ func (s *ActionsService) StartMySQLExplainAction(
return status.Error(codes.FailedPrecondition, "query or query_id is required")
}
- var q string
+ var q, schema string
switch {
case queryID != "":
res, err := s.qanClient.ExplainFingerprintByQueryID(ctx, serviceID, queryID)
@@ -77,8 +77,13 @@ func (s *ActionsService) StartMySQLExplainAction(
if res.PlaceholdersCount != uint32(len(placeholders)) {
return status.Error(codes.FailedPrecondition, "placeholders count is not correct")
}
-
q = res.ExplainFingerprint
+
+ s, err := s.qanClient.SchemaByQueryID(ctx, serviceID, queryID)
+ if err != nil {
+ return err
+ }
+ schema = s.Schema
default:
err := s.qanClient.QueryExists(ctx, serviceID, query)
if err != nil {
@@ -99,6 +104,7 @@ func (s *ActionsService) StartMySQLExplainAction(
Dsn: dsn,
Query: q,
Values: placeholders,
+ Schema: schema,
OutputFormat: format,
TlsFiles: &agentpb.TextFiles{
Files: files,
diff --git a/managed/services/agents/agents.go b/managed/services/agents/agents.go
index 0d7ffa4853..5a6c9bb036 100644
--- a/managed/services/agents/agents.go
+++ b/managed/services/agents/agents.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/agents_test.go b/managed/services/agents/agents_test.go
index 1497a0ac5d..ce0e846241 100644
--- a/managed/services/agents/agents_test.go
+++ b/managed/services/agents/agents_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/agentversion.go b/managed/services/agents/agentversion.go
index 427b501f22..9486511d3c 100644
--- a/managed/services/agents/agentversion.go
+++ b/managed/services/agents/agentversion.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/agentversion_test.go b/managed/services/agents/agentversion_test.go
index f6b22abb49..ebbad646fc 100644
--- a/managed/services/agents/agentversion_test.go
+++ b/managed/services/agents/agentversion_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/azure_database.go b/managed/services/agents/azure_database.go
index 2ccff9d96c..c53417306a 100644
--- a/managed/services/agents/azure_database.go
+++ b/managed/services/agents/azure_database.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/azure_database_test.go b/managed/services/agents/azure_database_test.go
index 0cdd20b727..17d1302fbc 100644
--- a/managed/services/agents/azure_database_test.go
+++ b/managed/services/agents/azure_database_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/channel/channel.go b/managed/services/agents/channel/channel.go
index 6fc8b8f9ed..1229ab6fab 100644
--- a/managed/services/agents/channel/channel.go
+++ b/managed/services/agents/channel/channel.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -28,7 +28,7 @@ import (
grpcstatus "google.golang.org/grpc/status"
"github.com/percona/pmm/api/agentpb"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
)
const (
diff --git a/managed/services/agents/channel/channel_test.go b/managed/services/agents/channel/channel_test.go
index 5f877fc60b..0944d85936 100644
--- a/managed/services/agents/channel/channel_test.go
+++ b/managed/services/agents/channel/channel_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/configure_test.go b/managed/services/agents/configure_test.go
index 2f56d2e1bb..be8d98b9a1 100644
--- a/managed/services/agents/configure_test.go
+++ b/managed/services/agents/configure_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/connection_checker.go b/managed/services/agents/connection_checker.go
index 3dc91d6f0f..256481be3b 100644
--- a/managed/services/agents/connection_checker.go
+++ b/managed/services/agents/connection_checker.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -31,7 +31,7 @@ import (
"github.com/percona/pmm/api/agentpb"
"github.com/percona/pmm/api/inventorypb"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
"github.com/percona/pmm/version"
)
diff --git a/managed/services/agents/deps.go b/managed/services/agents/deps.go
index e4b0c36014..9774ce6e73 100644
--- a/managed/services/agents/deps.go
+++ b/managed/services/agents/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -17,6 +17,7 @@ package agents
import (
"context"
+ "net/url"
"github.com/sirupsen/logrus"
@@ -39,6 +40,7 @@ type qanClient interface {
Collect(ctx context.Context, metricsBuckets []*agentpb.MetricsBucket) error
QueryExists(ctx context.Context, serviceID, query string) error
ExplainFingerprintByQueryID(ctx context.Context, serviceID, queryID string) (*qanpb.ExplainFingerprintByQueryIDReply, error)
+ SchemaByQueryID(ctx context.Context, serviceID, queryID string) (*qanpb.SchemaByQueryIDReply, error)
}
// retentionService is a subset of methods of backup.Client used by this package.
@@ -53,3 +55,11 @@ type jobsService interface {
handleJobResult(ctx context.Context, l *logrus.Entry, result *agentpb.JobResult)
handleJobProgress(ctx context.Context, progress *agentpb.JobProgress)
}
+
+// victoriaMetricsParams is a subset of methods of models.VMParams used by this package.
+// We use it instead of real type to avoid dependency cycle.
+type victoriaMetricsParams interface {
+ ExternalVM() bool
+ URLFor(path string) (*url.URL, error)
+ URL() string
+}
diff --git a/managed/services/agents/grpc/agent_server.go b/managed/services/agents/grpc/agent_server.go
index 42ef5b0d09..69eced0a99 100644
--- a/managed/services/agents/grpc/agent_server.go
+++ b/managed/services/agents/grpc/agent_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -40,7 +40,7 @@ func (s *agentServer) Connect(stream agentpb.Agent_ConnectServer) error {
return s.handler.Run(stream)
}
-// check interfaces
+// check interfaces.
var (
_ agentpb.AgentServer = (*agentServer)(nil)
)
diff --git a/managed/services/agents/handler.go b/managed/services/agents/handler.go
index ff45391e11..011ce90a84 100644
--- a/managed/services/agents/handler.go
+++ b/managed/services/agents/handler.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -31,7 +31,7 @@ import (
"github.com/percona/pmm/api/inventorypb"
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services/agents/channel"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
)
// Handler handles agent requests.
diff --git a/managed/services/agents/jobs.go b/managed/services/agents/jobs.go
index a78fffd381..56a6430e14 100644
--- a/managed/services/agents/jobs.go
+++ b/managed/services/agents/jobs.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/jobs_test.go b/managed/services/agents/jobs_test.go
index e6788e581d..cfb93abbc6 100644
--- a/managed/services/agents/jobs_test.go
+++ b/managed/services/agents/jobs_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/log_level.go b/managed/services/agents/log_level.go
index 57f236c1f0..2b33b472f8 100644
--- a/managed/services/agents/log_level.go
+++ b/managed/services/agents/log_level.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -22,11 +22,11 @@ import (
"github.com/percona/pmm/version"
)
-// Log level available in exporters with pmm 2.28
+// Log level available in exporters with pmm 2.28.
var exporterLogLevelCommandVersion = version.MustParse("2.27.99")
// withLogLevel - append CLI args --log.level
-// mysqld_exporter, node_exporter and postgres_exporter don't support --log.level=fatal
+// mysqld_exporter, node_exporter and postgres_exporter don't support --log.level=fatal.
func withLogLevel(args []string, logLevel *string, pmmAgentVersion *version.Parsed, supportLogLevelFatal bool) []string {
level := pointer.GetString(logLevel)
diff --git a/managed/services/agents/mongodb.go b/managed/services/agents/mongodb.go
index f0d14243fe..e51f4ba393 100644
--- a/managed/services/agents/mongodb.go
+++ b/managed/services/agents/mongodb.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/mongodb_test.go b/managed/services/agents/mongodb_test.go
index 9630519b50..9e01fe3eff 100644
--- a/managed/services/agents/mongodb_test.go
+++ b/managed/services/agents/mongodb_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/mysql.go b/managed/services/agents/mysql.go
index 56a67d7077..a2ecf8bfd3 100644
--- a/managed/services/agents/mysql.go
+++ b/managed/services/agents/mysql.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/mysql_test.go b/managed/services/agents/mysql_test.go
index 9b80f23483..0dd26767cc 100644
--- a/managed/services/agents/mysql_test.go
+++ b/managed/services/agents/mysql_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/node.go b/managed/services/agents/node.go
index ddd51efe2d..0189db757b 100644
--- a/managed/services/agents/node.go
+++ b/managed/services/agents/node.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/node_test.go b/managed/services/agents/node_test.go
index b050f8295f..e458847eca 100644
--- a/managed/services/agents/node_test.go
+++ b/managed/services/agents/node_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/postgresql.go b/managed/services/agents/postgresql.go
index e3503ed638..d777e56b47 100644
--- a/managed/services/agents/postgresql.go
+++ b/managed/services/agents/postgresql.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/postgresql_test.go b/managed/services/agents/postgresql_test.go
index 0e0131f3d9..312fa86757 100644
--- a/managed/services/agents/postgresql_test.go
+++ b/managed/services/agents/postgresql_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/proxysql.go b/managed/services/agents/proxysql.go
index cccec78944..94eb9694f7 100644
--- a/managed/services/agents/proxysql.go
+++ b/managed/services/agents/proxysql.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/proxysql_test.go b/managed/services/agents/proxysql_test.go
index ce4ee0ae0b..afcac95b5e 100644
--- a/managed/services/agents/proxysql_test.go
+++ b/managed/services/agents/proxysql_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/rds.go b/managed/services/agents/rds.go
index b882a30cc3..6f255f3e6b 100644
--- a/managed/services/agents/rds.go
+++ b/managed/services/agents/rds.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/rds_test.go b/managed/services/agents/rds_test.go
index 5cbf6d133f..52b4c6ebc3 100644
--- a/managed/services/agents/rds_test.go
+++ b/managed/services/agents/rds_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/registry.go b/managed/services/agents/registry.go
index f7ee0c7f9c..9f381c8ed8 100644
--- a/managed/services/agents/registry.go
+++ b/managed/services/agents/registry.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -32,7 +32,7 @@ import (
"github.com/percona/pmm/api/agentpb"
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services/agents/channel"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
"github.com/percona/pmm/version"
)
@@ -85,10 +85,12 @@ type Registry struct {
mRoundTrip prom.Summary
mClockDrift prom.Summary
mAgents prom.GaugeFunc
+
+ isExternalVM bool
}
// NewRegistry creates a new registry with given database connection.
-func NewRegistry(db *reform.DB) *Registry {
+func NewRegistry(db *reform.DB, externalVMChecker victoriaMetricsParams) *Registry {
agents := make(map[string]*pmmAgentInfo)
r := &Registry{
db: db,
@@ -123,6 +125,8 @@ func NewRegistry(db *reform.DB) *Registry {
Help: "Clock drift.",
Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
}),
+
+ isExternalVM: externalVMChecker.ExternalVM(),
}
r.mAgents = prom.NewGaugeFunc(prom.GaugeOpts{
@@ -160,7 +164,7 @@ func (r *Registry) register(stream agentpb.Agent_ConnectServer) (*pmmAgentInfo,
}
var node *models.Node
err = r.db.InTransaction(func(tx *reform.TX) error {
- node, err = authenticate(agentMD, tx.Querier)
+ node, err = r.authenticate(agentMD, tx.Querier)
if err != nil {
return err
}
@@ -204,7 +208,7 @@ func (r *Registry) register(stream agentpb.Agent_ConnectServer) (*pmmAgentInfo,
return agent, nil
}
-func authenticate(md *agentpb.AgentConnectMetadata, q *reform.Querier) (*models.Node, error) {
+func (r *Registry) authenticate(md *agentpb.AgentConnectMetadata, q *reform.Querier) (*models.Node, error) {
if md.ID == "" {
return nil, status.Error(codes.PermissionDenied, "Empty Agent ID.")
}
@@ -233,7 +237,7 @@ func authenticate(md *agentpb.AgentConnectMetadata, q *reform.Querier) (*models.
return nil, status.Errorf(codes.InvalidArgument, "Can't parse 'version' for pmm-agent with ID %q.", md.ID)
}
- if err := addOrRemoveVMAgent(q, md.ID, runsOnNodeID, agentVersion); err != nil {
+ if err := r.addOrRemoveVMAgent(q, md.ID, runsOnNodeID, agentVersion); err != nil {
return nil, err
}
@@ -296,18 +300,18 @@ func (r *Registry) ping(ctx context.Context, agent *pmmAgentInfo) error {
// addOrRemoveVMAgent - creates vmAgent agentType if pmm-agent's version supports it and agent not exists yet,
// otherwise ensures that vmAgent not exist for pmm-agent and pmm-agent's agents don't have push_metrics mode,
// removes it if needed.
-func addOrRemoveVMAgent(q *reform.Querier, pmmAgentID, runsOnNodeID string, pmmAgentVersion *version.Parsed) error {
+func (r *Registry) addOrRemoveVMAgent(q *reform.Querier, pmmAgentID, runsOnNodeID string, pmmAgentVersion *version.Parsed) error {
if pmmAgentVersion.Less(models.PMMAgentWithPushMetricsSupport) {
// ensure that vmagent not exists and agents dont have push_metrics.
return removeVMAgentFromPMMAgent(q, pmmAgentID)
}
- return addVMAgentToPMMAgent(q, pmmAgentID, runsOnNodeID)
+ return r.addVMAgentToPMMAgent(q, pmmAgentID, runsOnNodeID)
}
-func addVMAgentToPMMAgent(q *reform.Querier, pmmAgentID, runsOnNodeID string) error {
+func (r *Registry) addVMAgentToPMMAgent(q *reform.Querier, pmmAgentID, runsOnNodeID string) error {
// TODO remove it after fix
// https://jira.percona.com/browse/PMM-4420
- if runsOnNodeID == "pmm-server" {
+ if runsOnNodeID == "pmm-server" && !r.isExternalVM {
return nil
}
vmAgentType := models.VMAgentType
diff --git a/managed/services/agents/roster.go b/managed/services/agents/roster.go
index 4eba720bf2..4747075933 100644
--- a/managed/services/agents/roster.go
+++ b/managed/services/agents/roster.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/roster_test.go b/managed/services/agents/roster_test.go
index fc6b339a8c..d3e94482bc 100644
--- a/managed/services/agents/roster_test.go
+++ b/managed/services/agents/roster_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/state.go b/managed/services/agents/state.go
index c081af9d99..1bf2dc043b 100644
--- a/managed/services/agents/state.go
+++ b/managed/services/agents/state.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -28,7 +28,7 @@ import (
"github.com/percona/pmm/api/agentpb"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
"github.com/percona/pmm/version"
)
@@ -40,17 +40,19 @@ const (
// StateUpdater handles updating status of agents.
type StateUpdater struct {
- db *reform.DB
- r *Registry
- vmdb prometheusService
+ db *reform.DB
+ r *Registry
+ vmdb prometheusService
+ vmParams victoriaMetricsParams
}
// NewStateUpdater creates new agent state updater.
-func NewStateUpdater(db *reform.DB, r *Registry, vmdb prometheusService) *StateUpdater {
+func NewStateUpdater(db *reform.DB, r *Registry, vmdb prometheusService, vmParams victoriaMetricsParams) *StateUpdater {
return &StateUpdater{
- db: db,
- r: r,
- vmdb: vmdb,
+ db: db,
+ r: r,
+ vmdb: vmdb,
+ vmParams: vmParams,
}
}
@@ -180,7 +182,7 @@ func (u *StateUpdater) sendSetStateRequest(ctx context.Context, agent *pmmAgentI
if err != nil {
return errors.Wrapf(err, "cannot get agent scrape config for agent: %s", agent.id)
}
- agentProcesses[row.AgentID] = vmAgentConfig(string(scrapeCfg))
+ agentProcesses[row.AgentID] = vmAgentConfig(string(scrapeCfg), u.vmParams)
case models.NodeExporterType:
node, err := models.FindNodeByID(u.db.Querier, pointer.GetString(row.NodeID))
diff --git a/managed/services/agents/versioner.go b/managed/services/agents/versioner.go
index d91709128f..ae1bff828a 100644
--- a/managed/services/agents/versioner.go
+++ b/managed/services/agents/versioner.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/versioner_test.go b/managed/services/agents/versioner_test.go
index 53e1cc0b53..1135d44729 100644
--- a/managed/services/agents/versioner_test.go
+++ b/managed/services/agents/versioner_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/agents/vmagent.go b/managed/services/agents/vmagent.go
index f12d345d36..b13bfc9876 100644
--- a/managed/services/agents/vmagent.go
+++ b/managed/services/agents/vmagent.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -16,8 +16,10 @@
package agents
import (
+ "fmt"
"os"
"sort"
+ "strings"
"github.com/percona/pmm/api/agentpb"
"github.com/percona/pmm/api/inventorypb"
@@ -30,7 +32,11 @@ var (
)
// vmAgentConfig returns desired configuration of vmagent process.
-func vmAgentConfig(scrapeCfg string) *agentpb.SetStateRequest_AgentProcess {
+func vmAgentConfig(scrapeCfg string, params victoriaMetricsParams) *agentpb.SetStateRequest_AgentProcess {
+ serverURL := "{{.server_url}}/victoriametrics/"
+ if params.ExternalVM() {
+ serverURL = params.URL()
+ }
maxScrapeSize := maxScrapeSizeDefault
if space := os.Getenv(maxScrapeSizeEnv); space != "" {
maxScrapeSize = space
@@ -39,7 +45,7 @@ func vmAgentConfig(scrapeCfg string) *agentpb.SetStateRequest_AgentProcess {
interfaceToBind := envvars.GetInterfaceToBind()
args := []string{
- "-remoteWrite.url={{.server_url}}/victoriametrics/api/v1/write",
+ fmt.Sprintf("-remoteWrite.url=%sapi/v1/write", serverURL),
"-remoteWrite.tlsInsecureSkipVerify={{.server_insecure}}",
"-remoteWrite.tmpDataPath={{.tmp_dir}}/vmagent-temp-dir",
"-promscrape.config={{.TextFiles.vmagentscrapecfg}}",
@@ -50,13 +56,22 @@ func vmAgentConfig(scrapeCfg string) *agentpb.SetStateRequest_AgentProcess {
"-httpListenAddr=" + interfaceToBind + ":{{.listen_port}}",
// needed for login/password at client side.
"-envflag.enable=true",
+ "-envflag.prefix=VMAGENT_",
}
sort.Strings(args)
- envs := []string{
- "remoteWrite_basicAuth_username={{.server_username}}",
- "remoteWrite_basicAuth_password={{.server_password}}",
+ var envs []string
+ if !params.ExternalVM() {
+ envs = []string{
+ "VMAGENT_remoteWrite_basicAuth_username={{.server_username}}",
+ "VMAGENT_remoteWrite_basicAuth_password={{.server_password}}",
+ }
+ }
+ for _, env := range os.Environ() {
+ if strings.HasPrefix(env, envvars.ENVvmAgentPrefix) {
+ envs = append(envs, env)
+ }
}
sort.Strings(envs)
diff --git a/managed/services/agents/vmagent_test.go b/managed/services/agents/vmagent_test.go
index 2adc5fded8..a7bce4b3d6 100644
--- a/managed/services/agents/vmagent_test.go
+++ b/managed/services/agents/vmagent_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -19,17 +19,43 @@ import (
"testing"
"github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+
+ "github.com/percona/pmm/managed/models"
)
func TestMaxScrapeSize(t *testing.T) {
t.Run("by default 64MiB", func(t *testing.T) {
- actual := vmAgentConfig("")
+ params, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL)
+ require.NoError(t, err)
+ actual := vmAgentConfig("", params)
assert.Contains(t, actual.Args, "-promscrape.maxScrapeSize="+maxScrapeSizeDefault)
})
t.Run("overridden with ENV", func(t *testing.T) {
+ params, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL)
+ require.NoError(t, err)
newValue := "16MiB"
t.Setenv(maxScrapeSizeEnv, newValue)
- actual := vmAgentConfig("")
+ actual := vmAgentConfig("", params)
assert.Contains(t, actual.Args, "-promscrape.maxScrapeSize="+newValue)
})
+ t.Run("VMAGENT_ ENV variables", func(t *testing.T) {
+ params, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL)
+ require.NoError(t, err)
+ t.Setenv("VMAGENT_promscrape_maxScrapeSize", "16MiB")
+ t.Setenv("VM_remoteWrite_basicAuth_password", "password")
+ actual := vmAgentConfig("", params)
+ assert.Contains(t, actual.Env, "VMAGENT_promscrape_maxScrapeSize=16MiB")
+ assert.Contains(t, actual.Env, "VMAGENT_remoteWrite_basicAuth_username={{.server_username}}")
+ assert.NotContains(t, actual.Env, "VM_remoteWrite_basicAuth_password=password")
+ })
+ t.Run("External Victoria Metrics ENV variables", func(t *testing.T) {
+ params, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, "http://victoriametrics:8428")
+ require.NoError(t, err)
+ t.Setenv("VMAGENT_promscrape_maxScrapeSize", "16MiB")
+ actual := vmAgentConfig("", params)
+ assert.Contains(t, actual.Args, "-remoteWrite.url=http://victoriametrics:8428/api/v1/write")
+ assert.Contains(t, actual.Env, "VMAGENT_promscrape_maxScrapeSize=16MiB")
+ assert.NotContains(t, actual.Env, "VMAGENT_remoteWrite_basicAuth_username={{.server_username}}")
+ })
}
diff --git a/managed/services/alert_rule.go b/managed/services/alert_rule.go
index 563aa2dc5f..8c6517957a 100644
--- a/managed/services/alert_rule.go
+++ b/managed/services/alert_rule.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/alertmanager/alertmanager.go b/managed/services/alertmanager/alertmanager.go
index 12cf00aede..37027a72c8 100644
--- a/managed/services/alertmanager/alertmanager.go
+++ b/managed/services/alertmanager/alertmanager.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/alertmanager/alertmanager_test.go b/managed/services/alertmanager/alertmanager_test.go
index 9fe0e5ecd3..0ad493e571 100644
--- a/managed/services/alertmanager/alertmanager_test.go
+++ b/managed/services/alertmanager/alertmanager_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/backup/backup_service.go b/managed/services/backup/backup_service.go
index 07a59a37ae..2e730b366b 100644
--- a/managed/services/backup/backup_service.go
+++ b/managed/services/backup/backup_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -93,6 +93,10 @@ func (s *Service) PerformBackup(ctx context.Context, params PerformBackupParams)
errTX = s.db.InTransactionContext(ctx, &sql.TxOptions{Isolation: sql.LevelSerializable}, func(tx *reform.TX) error {
var err error
+ if err = services.CheckArtifactOverlapping(tx.Querier, params.ServiceID, params.LocationID, params.Folder); err != nil {
+ return err
+ }
+
svc, err = models.FindServiceByID(tx.Querier, params.ServiceID)
if err != nil {
return err
@@ -603,7 +607,7 @@ func checkArtifactMode(artifact *models.Artifact, pitrTimestamp time.Time) error
return nil
}
-// inTimeSpan checks whether given time is in the given range
+// inTimeSpan checks whether given time is in the given range.
func inTimeSpan(start, end, check time.Time) bool {
if start.Before(end) {
return !check.Before(start) && !check.After(end)
diff --git a/managed/services/backup/backup_service_test.go b/managed/services/backup/backup_service_test.go
index 0afeff434e..1b5d80801f 100644
--- a/managed/services/backup/backup_service_test.go
+++ b/managed/services/backup/backup_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -81,8 +81,6 @@ func TestPerformBackup(t *testing.T) {
mockedCompatibilityService := &mockCompatibilityService{}
backupService := NewService(db, mockedJobsService, mockedAgentService, mockedCompatibilityService, nil)
- artifactFolder := "artifact_folder"
-
s3Location, err := models.CreateBackupLocation(db.Querier, models.CreateBackupLocationParams{
Name: "Test s3 location",
Description: "Test s3 description",
@@ -164,7 +162,7 @@ func TestPerformBackup(t *testing.T) {
S3Config: tc.locationModel.S3Config,
}
mockedJobsService.On("StartMySQLBackupJob", mock.Anything, pointer.GetString(agent.PMMAgentID), time.Duration(0),
- mock.Anything, mock.Anything, locationConfig, artifactFolder).Return(nil).Once()
+ mock.Anything, mock.Anything, locationConfig, "artifact_folder").Return(nil).Once()
}
artifactID, err := backupService.PerformBackup(ctx, PerformBackupParams{
@@ -173,7 +171,7 @@ func TestPerformBackup(t *testing.T) {
Name: tc.name + "_" + "test_backup",
DataModel: tc.dataModel,
Mode: models.Snapshot,
- Folder: artifactFolder,
+ Folder: "artifact_folder",
})
if tc.expectedError != nil {
@@ -204,7 +202,7 @@ func TestPerformBackup(t *testing.T) {
Name: "test_backup",
DataModel: models.PhysicalDataModel,
Mode: models.PITR,
- Folder: artifactFolder,
+ Folder: "artifact_folder_2",
})
assert.ErrorIs(t, err, ErrIncompatibleDataModel)
assert.Empty(t, artifactID)
@@ -218,7 +216,7 @@ func TestPerformBackup(t *testing.T) {
Name: "test_backup",
DataModel: models.PhysicalDataModel,
Mode: models.PITR,
- Folder: artifactFolder,
+ Folder: "artifact_folder_3",
})
assert.ErrorContains(t, err, "Empty Service ID")
assert.Empty(t, artifactID)
@@ -233,7 +231,7 @@ func TestPerformBackup(t *testing.T) {
Name: "test_backup",
DataModel: models.PhysicalDataModel,
Mode: models.Incremental,
- Folder: artifactFolder,
+ Folder: "artifact_folder_4",
})
assert.ErrorContains(t, err, "the only supported backups mode for mongoDB is snapshot and PITR")
assert.Empty(t, artifactID)
diff --git a/managed/services/backup/compatibility_helpers.go b/managed/services/backup/compatibility_helpers.go
index 299a4c68e7..94f0f18882 100644
--- a/managed/services/backup/compatibility_helpers.go
+++ b/managed/services/backup/compatibility_helpers.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -221,10 +221,7 @@ func mongoDBBackupSoftwareInstalledAndCompatible(svm map[models.SoftwareName]str
}
// isOnlySameService checks if restore is only available to the same service.
-func isOnlySameService(artifactDBVersion string, serviceType models.ServiceType) bool {
- // allow restore to the same service if db version is unknown or service type is MongoDB.
- if artifactDBVersion == "" || serviceType == models.MongoDBServiceType {
- return true
- }
- return false
+func isOnlySameService(artifactDBVersion string) bool {
+ // allow restore only to the same service if db version is unknown.
+ return artifactDBVersion == ""
}
diff --git a/managed/services/backup/compatibility_helpers_test.go b/managed/services/backup/compatibility_helpers_test.go
index 7795d73187..9d5e975572 100644
--- a/managed/services/backup/compatibility_helpers_test.go
+++ b/managed/services/backup/compatibility_helpers_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/backup/compatibility_service.go b/managed/services/backup/compatibility_service.go
index af2536634d..1e6c70c3ba 100644
--- a/managed/services/backup/compatibility_service.go
+++ b/managed/services/backup/compatibility_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -96,13 +96,29 @@ func (s *CompatibilityService) findCompatibleServiceIDs(artifactModel *models.Ar
compatibleServiceIDs := make([]string, 0, len(svs))
for _, sv := range svs {
svm := softwareVersionsToMap(sv.SoftwareVersions)
+ var (
+ serviceDBVersion string
+ err error
+ )
- if err := mySQLBackupSoftwareInstalledAndCompatible(svm); err != nil {
+ switch artifactModel.Vendor {
+ case "mysql":
+ serviceDBVersion = svm[models.MysqldSoftwareName]
+ err = mySQLBackupSoftwareInstalledAndCompatible(svm)
+
+ case "mongodb":
+ serviceDBVersion = svm[models.MongoDBSoftwareName]
+ err = mongoDBBackupSoftwareInstalledAndCompatible(svm)
+
+ default:
+ return nil
+ }
+
+ if err != nil {
s.l.WithError(err).Debugf("skip incompatible service id %q", sv.ServiceID)
continue
}
- serviceDBVersion := svm[models.MysqldSoftwareName]
if artifactModel.DBVersion != serviceDBVersion {
s.l.Debugf("skip incompatible service id %q: artifact version %q != db version %q\"", sv.ServiceID,
artifactModel.DBVersion, serviceDBVersion)
@@ -174,7 +190,7 @@ func (s *CompatibilityService) FindArtifactCompatibleServices(
return err
}
- onlySameService := isOnlySameService(artifactModel.DBVersion, serviceType)
+ onlySameService := isOnlySameService(artifactModel.DBVersion)
if onlySameService {
service, err := models.FindServiceByID(tx.Querier, artifactModel.ServiceID)
@@ -230,7 +246,7 @@ func (s *CompatibilityService) CheckArtifactCompatibility(artifactID, targetDBVe
return s.artifactCompatibility(artifactModel, serviceModel, targetDBVersion)
}
-// artifactCompatibility contains logic for CheckArtifactCompatibility
+// artifactCompatibility contains logic for CheckArtifactCompatibility.
func (s *CompatibilityService) artifactCompatibility(artifactModel *models.Artifact, serviceModel *models.Service, targetDBVersion string) error {
var err error
if artifactModel.DBVersion != "" && artifactModel.DBVersion != targetDBVersion {
diff --git a/managed/services/backup/compatibility_service_test.go b/managed/services/backup/compatibility_service_test.go
index eb3724dba8..4859073fd8 100644
--- a/managed/services/backup/compatibility_service_test.go
+++ b/managed/services/backup/compatibility_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -212,100 +212,162 @@ func TestFindCompatibleServiceIDs(t *testing.T) {
t.Parallel()
cSvc := NewCompatibilityService(nil, nil)
- testSet := []*models.ServiceSoftwareVersions{
- {
- ServiceID: "1",
- SoftwareVersions: models.SoftwareVersions{
- {Name: models.MysqldSoftwareName, Version: ""},
- {Name: models.XtrabackupSoftwareName, Version: "8.0.25"},
- {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
- {Name: models.QpressSoftwareName, Version: "1.1"},
+ t.Run("mysql", func(t *testing.T) {
+ testSet := []*models.ServiceSoftwareVersions{
+ {
+ ServiceID: "1",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MysqldSoftwareName, Version: ""},
+ {Name: models.XtrabackupSoftwareName, Version: "8.0.25"},
+ {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
+ {Name: models.QpressSoftwareName, Version: "1.1"},
+ },
},
- },
- {
- ServiceID: "2",
- SoftwareVersions: models.SoftwareVersions{
- {Name: models.MysqldSoftwareName, Version: "8.0.25"},
- {Name: models.XtrabackupSoftwareName, Version: "8.0.24"},
- {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
- {Name: models.QpressSoftwareName, Version: "1.1"},
+ {
+ ServiceID: "2",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MysqldSoftwareName, Version: "8.0.25"},
+ {Name: models.XtrabackupSoftwareName, Version: "8.0.24"},
+ {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
+ {Name: models.QpressSoftwareName, Version: "1.1"},
+ },
},
- },
- {
- ServiceID: "3",
- SoftwareVersions: models.SoftwareVersions{
- {Name: models.MysqldSoftwareName, Version: "8.0.25"},
- {Name: models.XtrabackupSoftwareName, Version: "8.0.25"},
- {Name: models.XbcloudSoftwareName, Version: "8.0.24"},
- {Name: models.QpressSoftwareName, Version: "1.1"},
+ {
+ ServiceID: "3",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MysqldSoftwareName, Version: "8.0.25"},
+ {Name: models.XtrabackupSoftwareName, Version: "8.0.25"},
+ {Name: models.XbcloudSoftwareName, Version: "8.0.24"},
+ {Name: models.QpressSoftwareName, Version: "1.1"},
+ },
},
- },
- {
- ServiceID: "4",
- SoftwareVersions: models.SoftwareVersions{
- {Name: models.MysqldSoftwareName, Version: "8.0.25"},
- {Name: models.XtrabackupSoftwareName, Version: "8.0.25"},
- {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
- {Name: models.QpressSoftwareName, Version: ""},
+ {
+ ServiceID: "4",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MysqldSoftwareName, Version: "8.0.25"},
+ {Name: models.XtrabackupSoftwareName, Version: "8.0.25"},
+ {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
+ {Name: models.QpressSoftwareName, Version: ""},
+ },
},
- },
- {
- ServiceID: "5",
- SoftwareVersions: models.SoftwareVersions{
- {Name: models.MysqldSoftwareName, Version: "8.0.25"},
- {Name: models.XtrabackupSoftwareName, Version: "8.0.25"},
- {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
- {Name: models.QpressSoftwareName, Version: "1.1"},
+ {
+ ServiceID: "5",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MysqldSoftwareName, Version: "8.0.25"},
+ {Name: models.XtrabackupSoftwareName, Version: "8.0.25"},
+ {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
+ {Name: models.QpressSoftwareName, Version: "1.1"},
+ },
},
- },
- {
- ServiceID: "6",
- SoftwareVersions: models.SoftwareVersions{
- {Name: models.MysqldSoftwareName, Version: "8.0.25"},
- {Name: models.XtrabackupSoftwareName, Version: ""},
- {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
- {Name: models.QpressSoftwareName, Version: "1.1"},
+ {
+ ServiceID: "6",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MysqldSoftwareName, Version: "8.0.25"},
+ {Name: models.XtrabackupSoftwareName, Version: ""},
+ {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
+ {Name: models.QpressSoftwareName, Version: "1.1"},
+ },
},
- },
- {
- ServiceID: "7",
- SoftwareVersions: models.SoftwareVersions{
- {Name: models.MysqldSoftwareName, Version: "8.0.24"},
- {Name: models.XtrabackupSoftwareName, Version: "8.0.25"},
- {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
- {Name: models.QpressSoftwareName, Version: "1.1"},
+ {
+ ServiceID: "7",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MysqldSoftwareName, Version: "8.0.24"},
+ {Name: models.XtrabackupSoftwareName, Version: "8.0.25"},
+ {Name: models.XbcloudSoftwareName, Version: "8.0.25"},
+ {Name: models.QpressSoftwareName, Version: "1.1"},
+ },
},
- },
- {
- ServiceID: "8",
- SoftwareVersions: models.SoftwareVersions{
- {Name: models.MysqldSoftwareName, Version: "8.0.25"},
- {Name: models.XtrabackupSoftwareName, Version: "8.0.26"},
- {Name: models.XbcloudSoftwareName, Version: "8.0.26"},
- {Name: models.QpressSoftwareName, Version: "1.1"},
+ {
+ ServiceID: "8",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MysqldSoftwareName, Version: "8.0.25"},
+ {Name: models.XtrabackupSoftwareName, Version: "8.0.26"},
+ {Name: models.XbcloudSoftwareName, Version: "8.0.26"},
+ {Name: models.QpressSoftwareName, Version: "1.1"},
+ },
},
- },
- }
+ }
- t.Run("empty db version", func(t *testing.T) {
- t.Parallel()
- res := cSvc.findCompatibleServiceIDs(&models.Artifact{DBVersion: ""}, testSet)
- assert.Equal(t, 0, len(res))
- })
- t.Run("matches several", func(t *testing.T) {
- t.Parallel()
- res := cSvc.findCompatibleServiceIDs(&models.Artifact{DBVersion: "8.0.25"}, testSet)
- assert.ElementsMatch(t, []string{"5", "8"}, res)
- })
- t.Run("matches one", func(t *testing.T) {
- t.Parallel()
- res := cSvc.findCompatibleServiceIDs(&models.Artifact{DBVersion: "8.0.24"}, testSet)
- assert.ElementsMatch(t, []string{"7"}, res)
+ t.Run("empty db version", func(t *testing.T) {
+ t.Parallel()
+ res := cSvc.findCompatibleServiceIDs(&models.Artifact{Vendor: "mysql", DBVersion: ""}, testSet)
+ assert.Equal(t, 0, len(res))
+ })
+ t.Run("matches several", func(t *testing.T) {
+ t.Parallel()
+ res := cSvc.findCompatibleServiceIDs(&models.Artifact{Vendor: "mysql", DBVersion: "8.0.25"}, testSet)
+ assert.ElementsMatch(t, []string{"5", "8"}, res)
+ })
+ t.Run("matches one", func(t *testing.T) {
+ t.Parallel()
+ res := cSvc.findCompatibleServiceIDs(&models.Artifact{Vendor: "mysql", DBVersion: "8.0.24"}, testSet)
+ assert.ElementsMatch(t, []string{"7"}, res)
+ })
+ t.Run("artifact version greater then existing services", func(t *testing.T) {
+ t.Parallel()
+ res := cSvc.findCompatibleServiceIDs(&models.Artifact{Vendor: "mysql", DBVersion: "8.0.30"}, testSet)
+ assert.Equal(t, 0, len(res))
+ })
})
- t.Run("artifact version greater then existing services", func(t *testing.T) {
- t.Parallel()
- res := cSvc.findCompatibleServiceIDs(&models.Artifact{DBVersion: "8.0.30"}, testSet)
- assert.Equal(t, 0, len(res))
+
+ t.Run("mongo", func(t *testing.T) {
+ testSet := []*models.ServiceSoftwareVersions{
+ {
+ ServiceID: "1",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MongoDBSoftwareName, Version: ""},
+ {Name: models.PBMSoftwareName, Version: "2.0.1"},
+ },
+ },
+ {
+ ServiceID: "2",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MongoDBSoftwareName, Version: "6.0.5"},
+ {Name: models.PBMSoftwareName, Version: "2.0.0"},
+ },
+ },
+ {
+ ServiceID: "3",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MongoDBSoftwareName, Version: "6.0.5"},
+ {Name: models.PBMSoftwareName, Version: ""},
+ },
+ },
+ {
+ ServiceID: "4",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MongoDBSoftwareName, Version: "6.0.5"},
+ {Name: models.PBMSoftwareName, Version: "2.0.1"},
+ },
+ },
+ {
+ ServiceID: "5",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MongoDBSoftwareName, Version: "5.0.5"},
+ {Name: models.PBMSoftwareName, Version: "2.0.5"},
+ },
+ },
+ {
+ ServiceID: "6",
+ SoftwareVersions: models.SoftwareVersions{
+ {Name: models.MongoDBSoftwareName, Version: "5.0.5"},
+ {Name: models.PBMSoftwareName, Version: "2.0.5"},
+ },
+ },
+ }
+
+ t.Run("empty db version", func(t *testing.T) {
+ res := cSvc.findCompatibleServiceIDs(&models.Artifact{Vendor: "mongodb", DBVersion: ""}, testSet)
+ assert.Equal(t, 0, len(res))
+ })
+ t.Run("matches several", func(t *testing.T) {
+ res := cSvc.findCompatibleServiceIDs(&models.Artifact{Vendor: "mongodb", DBVersion: "5.0.5"}, testSet)
+ assert.ElementsMatch(t, []string{"5", "6"}, res)
+ })
+ t.Run("matches one", func(t *testing.T) {
+ res := cSvc.findCompatibleServiceIDs(&models.Artifact{Vendor: "mongodb", DBVersion: "6.0.5"}, testSet)
+ assert.ElementsMatch(t, []string{"4"}, res)
+ })
})
}
@@ -376,24 +438,6 @@ func TestFindArtifactCompatibleServices(t *testing.T) {
errString: "",
expectEmptyResult: false,
},
- {
- name: "non-mysql db vendor",
- artifactIDToSearch: "test_artifact_id",
- artifact: models.Artifact{
- ID: "test_artifact_id",
- Name: " ",
- Vendor: "mongodb",
- DBVersion: "8.0.25",
- LocationID: "test_location_id",
- ServiceID: "test_service_id",
- DataModel: " ",
- Mode: " ",
- Status: " ",
- Type: " ",
- },
- errString: "",
- expectEmptyResult: false,
- },
{
name: "no software versions data for mysql",
artifactIDToSearch: "test_artifact_id",
diff --git a/managed/services/backup/deps.go b/managed/services/backup/deps.go
index 86c0caf8a4..3ec7340976 100644
--- a/managed/services/backup/deps.go
+++ b/managed/services/backup/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/backup/errors.go b/managed/services/backup/errors.go
index f6b5d15c6b..4001dbba8e 100644
--- a/managed/services/backup/errors.go
+++ b/managed/services/backup/errors.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/backup/metrics.go b/managed/services/backup/metrics.go
new file mode 100644
index 0000000000..1aa661deca
--- /dev/null
+++ b/managed/services/backup/metrics.go
@@ -0,0 +1,113 @@
+// Copyright (C) 2023 Percona LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package backup
+
+import (
+ "context"
+ "time"
+
+ "github.com/pkg/errors"
+ prom "github.com/prometheus/client_golang/prometheus"
+ "github.com/sirupsen/logrus"
+ "gopkg.in/reform.v1"
+
+ "github.com/percona/pmm/managed/models"
+)
+
+const (
+ requestTimeout = 3 * time.Second
+ artifactExists float64 = 1
+ prometheusNamespace = "pmm_managed"
+ prometheusSubsystem = "backups"
+)
+
+type MetricsCollector struct {
+ db *reform.DB
+ l *logrus.Entry
+
+ mArtifactsDesc *prom.Desc
+}
+
+func NewMetricsCollector(db *reform.DB) *MetricsCollector {
+ return &MetricsCollector{
+ db: db,
+ l: logrus.WithField("component", "backups/metrics"),
+ mArtifactsDesc: prom.NewDesc(
+ prom.BuildFQName(prometheusNamespace, prometheusSubsystem, "artifacts"),
+ "Artifacts",
+ []string{
+ "artifact_id", "artifact_name", "artifact_vendor", "service_id", "service_name",
+ "type", "db_version", "data_model", "mode", "status",
+ },
+ nil),
+ }
+}
+
+func (c *MetricsCollector) Describe(ch chan<- *prom.Desc) {
+ ch <- c.mArtifactsDesc
+}
+
+func (c *MetricsCollector) Collect(ch chan<- prom.Metric) {
+ ctx, cancelCtx := context.WithTimeout(context.Background(), requestTimeout)
+ defer cancelCtx()
+
+ var artifacts []*models.Artifact
+ var services map[string]*models.Service
+ errTx := c.db.InTransactionContext(ctx, nil, func(t *reform.TX) error {
+ var err error
+ artifacts, err = models.FindArtifacts(t.Querier, models.ArtifactFilters{})
+ if err != nil {
+ return errors.WithStack(err)
+ }
+
+ serviceIDs := make([]string, 0, len(artifacts))
+ for _, artifact := range artifacts {
+ serviceIDs = append(serviceIDs, artifact.ServiceID)
+ }
+
+ services, err = models.FindServicesByIDs(t.Querier, serviceIDs)
+ if err != nil {
+ return errors.WithStack(err)
+ }
+ return nil
+ })
+ if errTx != nil {
+ c.l.Warnf("Failed to get artifacts: %v", errTx)
+ return
+ }
+
+ for _, artifact := range artifacts {
+ var serviceName string
+ if service, ok := services[artifact.ServiceID]; ok {
+ serviceName = service.ServiceName
+ }
+
+ ch <- prom.MustNewConstMetric(
+ c.mArtifactsDesc,
+ prom.GaugeValue,
+ artifactExists,
+ artifact.ID,
+ artifact.Name,
+ artifact.Vendor,
+ artifact.ServiceID,
+ serviceName,
+ string(artifact.Type),
+ artifact.DBVersion,
+ string(artifact.DataModel),
+ string(artifact.Mode),
+ string(artifact.Status))
+ }
+}
diff --git a/managed/services/backup/mock_agent_service_test.go b/managed/services/backup/mock_agent_service_test.go
index 3be56de1ac..88f28a59c4 100644
--- a/managed/services/backup/mock_agent_service_test.go
+++ b/managed/services/backup/mock_agent_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/backup/mock_compatibility_service_test.go b/managed/services/backup/mock_compatibility_service_test.go
index e0cf6b26df..ba208d718f 100644
--- a/managed/services/backup/mock_compatibility_service_test.go
+++ b/managed/services/backup/mock_compatibility_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/backup/mock_jobs_service_test.go b/managed/services/backup/mock_jobs_service_test.go
index b85845eb81..4aff8d72e6 100644
--- a/managed/services/backup/mock_jobs_service_test.go
+++ b/managed/services/backup/mock_jobs_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/backup/mock_pbm_pitr_service_test.go b/managed/services/backup/mock_pbm_pitr_service_test.go
index b9a9bd71dd..d39a3ebb15 100644
--- a/managed/services/backup/mock_pbm_pitr_service_test.go
+++ b/managed/services/backup/mock_pbm_pitr_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/backup/mock_removal_service_test.go b/managed/services/backup/mock_removal_service_test.go
index 8fcd7e6ef4..d21aff6858 100644
--- a/managed/services/backup/mock_removal_service_test.go
+++ b/managed/services/backup/mock_removal_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/backup/mock_storage_test.go b/managed/services/backup/mock_storage_test.go
index 699052bd20..cbd607a9b1 100644
--- a/managed/services/backup/mock_storage_test.go
+++ b/managed/services/backup/mock_storage_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/backup/mock_versioner_test.go b/managed/services/backup/mock_versioner_test.go
index 10830471f6..9f9f8d830e 100644
--- a/managed/services/backup/mock_versioner_test.go
+++ b/managed/services/backup/mock_versioner_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/backup/pitr_timerange_service.go b/managed/services/backup/pitr_timerange_service.go
index 8f691a7777..84050aa139 100644
--- a/managed/services/backup/pitr_timerange_service.go
+++ b/managed/services/backup/pitr_timerange_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -37,7 +37,7 @@ const (
var errUnsupportedLocation = errors.New("unsupported location config")
-// PBMPITRService helps to perform PITR chunks lookup in a backup storage
+// PBMPITRService helps to perform PITR chunks lookup in a backup storage.
type PBMPITRService struct {
l *logrus.Entry
}
@@ -49,7 +49,7 @@ func NewPBMPITRService() *PBMPITRService {
}
}
-// oplogChunk is index metadata for the oplog chunks
+// oplogChunk is index metadata for the oplog chunks.
type oplogChunk struct {
RS string `bson:"rs"`
FName string `bson:"fname"`
@@ -59,7 +59,7 @@ type oplogChunk struct {
size int64 `bson:"-"`
}
-// Timeline is an internal representation of a PITR Timeline
+// Timeline is an internal representation of a PITR Timeline.
type Timeline struct {
ReplicaSet string `json:"replica_set"`
Start uint32 `json:"start"`
@@ -79,7 +79,7 @@ func (x gaps) Less(i, j int) bool {
}
func (x gaps) Swap(i, j int) { x[i], x[j] = x[j], x[i] }
-// compressionType is the type of compression used for PITR oplog
+// compressionType is the type of compression used for PITR oplog.
type compressionType string
const (
@@ -91,7 +91,7 @@ const (
compressionTypeZstandard compressionType = "zstd"
)
-// file return compression alg based on given file extension
+// file return compression alg based on given file extension.
func file(ext string) compressionType {
switch ext {
case "gz":
@@ -190,7 +190,7 @@ func trimTimelines(timelines []Timeline) {
// current format is 20200715155939-0.20200715160029-1.oplog.snappy
// (https://github.com/percona/percona-backup-mongodb/wiki/PITR:-storage-layout)
//
-// !!! Should be agreed with pbm/pitr.chunkPath()
+// !!! Should be agreed with pbm/pitr.chunkPath().
func pitrMetaFromFileName(prefix, f string) *oplogChunk {
ppath := strings.Split(f, "/")
if len(ppath) < 2 {
@@ -251,7 +251,7 @@ func getTimelines(slices []*oplogChunk) []Timeline {
var timelines []Timeline
var prevEnd primitive.Timestamp
for _, s := range slices {
- if prevEnd.T != 0 && primitive.CompareTimestamp(prevEnd, s.StartTS) == -1 {
+ if prevEnd.T != 0 && prevEnd.Compare(s.StartTS) == -1 {
timelines = append(timelines, tl)
tl = Timeline{}
}
@@ -269,7 +269,7 @@ func getTimelines(slices []*oplogChunk) []Timeline {
}
// mergeTimelines merges overlapping sets on timelines
-// it presumes timelines are sorted and don't start from 0
+// it presumes timelines are sorted and don't start from 0.
func mergeTimelines(timelines ...[]Timeline) []Timeline {
// fast paths
if len(timelines) == 0 {
diff --git a/managed/services/backup/pitr_timerange_service_test.go b/managed/services/backup/pitr_timerange_service_test.go
index ed9765293b..4f7e3cbfee 100644
--- a/managed/services/backup/pitr_timerange_service_test.go
+++ b/managed/services/backup/pitr_timerange_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/backup/removal_service.go b/managed/services/backup/removal_service.go
index ae0733acdf..dff93e5cac 100644
--- a/managed/services/backup/removal_service.go
+++ b/managed/services/backup/removal_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -91,18 +91,12 @@ func (s *RemovalService) DeleteArtifact(storage Storage, artifactID string, remo
return
}
- service, err := models.FindServiceByID(s.db.Querier, artifact.ServiceID)
- if err != nil {
- s.l.WithError(err).Error("couldn't get service")
- return
- }
-
if err = s.deleteArtifactFiles(context.Background(), storage, location, artifact, len(artifact.MetadataList)); err != nil {
s.l.WithError(err).Error("couldn't delete artifact files")
return
}
- if service.ServiceType == models.MongoDBServiceType && artifact.Mode == models.PITR {
+ if artifact.Vendor == string(models.MongoDBServiceType) && artifact.Mode == models.PITR {
if err = s.deleteArtifactPITRChunks(context.Background(), storage, location, artifact, nil); err != nil {
s.l.WithError(err).Error("couldn't delete artifact PITR chunks")
return
diff --git a/managed/services/backup/removal_service_test.go b/managed/services/backup/removal_service_test.go
index d88b35cb9e..b0f9b2dc13 100644
--- a/managed/services/backup/removal_service_test.go
+++ b/managed/services/backup/removal_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -185,7 +185,7 @@ func TestDeleteArtifact(t *testing.T) {
artifact, err := models.CreateArtifact(db.Querier, models.CreateArtifactParams{
Name: "artifact_name",
- Vendor: "MongoDB",
+ Vendor: "mongodb",
LocationID: locationRes.ID,
ServiceID: *agent.ServiceID,
DataModel: models.LogicalDataModel,
diff --git a/managed/services/backup/retention_service.go b/managed/services/backup/retention_service.go
index c46a56e1ec..562babc703 100644
--- a/managed/services/backup/retention_service.go
+++ b/managed/services/backup/retention_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/backup/retention_service_test.go b/managed/services/backup/retention_service_test.go
index 738729fb8f..66bc5fb4b0 100644
--- a/managed/services/backup/retention_service_test.go
+++ b/managed/services/backup/retention_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/checks/checks.go b/managed/services/checks/checks.go
index 72c915ed30..4a58993930 100644
--- a/managed/services/checks/checks.go
+++ b/managed/services/checks/checks.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -33,7 +33,6 @@ import (
"time"
"github.com/percona-platform/saas/pkg/check"
- "github.com/percona-platform/saas/pkg/common"
"github.com/pkg/errors"
v1 "github.com/prometheus/client_golang/api/prometheus/v1"
prom "github.com/prometheus/client_golang/prometheus"
@@ -58,7 +57,6 @@ const (
// Environment variables that affect checks service; only for testing.
envCheckFile = "PERCONA_TEST_CHECKS_FILE"
- envResendInterval = "PERCONA_TEST_CHECKS_RESEND_INTERVAL"
envDisableStartDelay = "PERCONA_TEST_CHECKS_DISABLE_START_DELAY"
checkExecutionTimeout = 5 * time.Minute // limits execution time for every single check
@@ -67,14 +65,9 @@ const (
scriptExecutionTimeout = 5 * time.Second // time limit for running pmm-managed-starlark
resultCheckInterval = time.Second
- // Sync with API tests.
- resolveTimeoutFactor = 3
- defaultResendInterval = 2 * time.Second
-
prometheusNamespace = "pmm_managed"
prometheusSubsystem = "advisor"
- alertsPrefix = "/stt/"
maxSupportedVersion = 2
)
@@ -91,17 +84,15 @@ var (
// Service is responsible for interactions with Percona Check service.
type Service struct {
- platformClient *platform.Client
- agentsRegistry agentsRegistry
- alertmanagerService alertmanagerService
- db *reform.DB
- alertsRegistry *registry
- vmClient v1.API
- clickhouseDB *sql.DB
+ platformClient *platform.Client
+ agentsRegistry agentsRegistry
+ db *reform.DB
+ alertsRegistry *registry
+ vmClient v1.API
+ clickhouseDB *sql.DB
l *logrus.Entry
startDelay time.Duration
- resendInterval time.Duration
platformPublicKeys []string
localChecksFile string // For testing
@@ -131,18 +122,11 @@ func New(
db *reform.DB,
platformClient *platform.Client,
agentsRegistry agentsRegistry,
- alertmanagerService alertmanagerService,
vmClient v1.API,
clickhouseDB *sql.DB,
) *Service {
l := logrus.WithField("component", "checks")
- resendInterval := defaultResendInterval
- if d, err := time.ParseDuration(os.Getenv(envResendInterval)); err == nil && d > 0 {
- l.Warnf("Interval changed to %s.", d)
- resendInterval = d
- }
-
var platformPublicKeys []string
if k := envvars.GetPlatformPublicKeys(); k != nil {
l.Warnf("Percona Platform public keys changed to %q.", k)
@@ -150,17 +134,15 @@ func New(
}
s := &Service{
- db: db,
- agentsRegistry: agentsRegistry,
- alertmanagerService: alertmanagerService,
- alertsRegistry: newRegistry(resolveTimeoutFactor * resendInterval),
- vmClient: vmClient,
- clickhouseDB: clickhouseDB,
+ db: db,
+ agentsRegistry: agentsRegistry,
+ alertsRegistry: newRegistry(),
+ vmClient: vmClient,
+ clickhouseDB: clickhouseDB,
l: l,
platformClient: platformClient,
startDelay: defaultStartDelay,
- resendInterval: resendInterval,
platformPublicKeys: platformPublicKeys,
localChecksFile: os.Getenv(envCheckFile),
@@ -226,12 +208,6 @@ func (s *Service) Run(ctx context.Context) {
var wg sync.WaitGroup
- wg.Add(1)
- go func() {
- defer wg.Done()
- s.resendAlerts(ctx)
- }()
-
wg.Add(1)
go func() {
defer wg.Done()
@@ -241,23 +217,6 @@ func (s *Service) Run(ctx context.Context) {
wg.Wait()
}
-// resendAlerts resends collected alerts until ctx is canceled.
-func (s *Service) resendAlerts(ctx context.Context) {
- t := time.NewTicker(s.resendInterval)
- defer t.Stop()
-
- for {
- s.alertmanagerService.SendAlerts(ctx, s.alertsRegistry.collect())
-
- select {
- case <-ctx.Done():
- return
- case <-t.C:
- // nothing, continue for loop
- }
- }
-}
-
// runChecksLoop starts checks execution loop.
func (s *Service) runChecksLoop(ctx context.Context) {
// First checks run, start all checks from all groups.
@@ -298,11 +257,11 @@ func (s *Service) GetSecurityCheckResults() ([]services.CheckResult, error) {
return nil, services.ErrAdvisorsDisabled
}
- return s.alertsRegistry.getCheckResults(), nil
+ return s.alertsRegistry.getCheckResults(""), nil
}
// GetChecksResults returns the failed checks for a given service from AlertManager.
-func (s *Service) GetChecksResults(ctx context.Context, serviceID string) ([]services.CheckResult, error) {
+func (s *Service) GetChecksResults(_ context.Context, serviceID string) ([]services.CheckResult, error) {
settings, err := models.GetSettings(s.db)
if err != nil {
return nil, err
@@ -312,59 +271,7 @@ func (s *Service) GetChecksResults(ctx context.Context, serviceID string) ([]ser
return nil, services.ErrAdvisorsDisabled
}
- filters := &services.FilterParams{
- IsCheck: true,
- ServiceID: serviceID,
- }
- res, err := s.alertmanagerService.GetAlerts(ctx, filters)
- if err != nil {
- return nil, err
- }
-
- checkResults := make([]services.CheckResult, 0, len(res))
- for _, alert := range res {
- checkResults = append(checkResults, services.CheckResult{
- CheckName: alert.Labels[model.AlertNameLabel],
- Silenced: len(alert.Status.SilencedBy) != 0,
- AlertID: alert.Labels["alert_id"],
- Interval: check.Interval(alert.Labels["interval_group"]),
- Target: services.Target{
- AgentID: alert.Labels["agent_id"],
- ServiceID: alert.Labels["service_id"],
- ServiceName: alert.Labels["service_name"],
- NodeName: alert.Labels["node_name"],
- Labels: alert.Labels,
- },
- Result: check.Result{
- Summary: alert.Annotations["summary"],
- Description: alert.Annotations["description"],
- ReadMoreURL: alert.Annotations["read_more_url"],
- Severity: common.ParseSeverity(alert.Labels["severity"]),
- Labels: alert.Labels,
- },
- })
- }
- return checkResults, nil
-}
-
-// ToggleCheckAlert toggles the silence state of the check with the provided alertID.
-func (s *Service) ToggleCheckAlert(ctx context.Context, alertID string, silence bool) error {
- filters := &services.FilterParams{
- IsCheck: true,
- AlertID: alertID,
- }
- res, err := s.alertmanagerService.GetAlerts(ctx, filters)
- if err != nil {
- return errors.Wrapf(err, "failed to get alerts with id: %s", alertID)
- }
-
- if silence {
- err = s.alertmanagerService.SilenceAlerts(ctx, res)
- } else {
- err = s.alertmanagerService.UnsilenceAlerts(ctx, res)
- }
-
- return err
+ return s.alertsRegistry.getCheckResults(serviceID), nil
}
// runChecksGroup downloads and executes Advisors checks that should run in the interval specified by intervalGroup.
@@ -411,11 +318,24 @@ func (s *Service) run(ctx context.Context, intervalGroup check.Interval, checkNa
return errors.WithStack(err)
}
- if err := s.executeChecks(ctx, intervalGroup, checkNames); err != nil {
+ res, err := s.executeChecks(ctx, intervalGroup, checkNames)
+ if err != nil {
return errors.WithStack(err)
}
- s.alertmanagerService.SendAlerts(ctx, s.alertsRegistry.collect())
+ switch {
+ case len(checkNames) != 0:
+ // If we run some specific checks, delete previous results for them.
+ s.alertsRegistry.deleteByName(checkNames)
+ case intervalGroup != "":
+ // If we run whole interval group, delete previous results for that group.
+ s.alertsRegistry.deleteByInterval(intervalGroup)
+ default:
+ // If we run all checks, delete all previous results.
+ s.alertsRegistry.cleanup()
+ }
+
+ s.alertsRegistry.set(res)
return nil
}
@@ -706,46 +626,32 @@ func (s *Service) filterChecks(checks map[string]check.Check, group check.Interv
// executeChecks runs checks for all reachable services. If intervalGroup specified only checks from that group will be
// executed. If checkNames specified then only matched checks will be executed.
-func (s *Service) executeChecks(ctx context.Context, intervalGroup check.Interval, checkNames []string) error {
+func (s *Service) executeChecks(ctx context.Context, intervalGroup check.Interval, checkNames []string) ([]services.CheckResult, error) {
disabledChecks, err := s.GetDisabledChecks()
if err != nil {
- return errors.WithStack(err)
+ return nil, errors.WithStack(err)
}
- var checkResults []services.CheckResult
+ var res []services.CheckResult
checks, err := s.GetChecks()
if err != nil {
- return errors.WithStack(err)
+ return nil, errors.WithStack(err)
}
- mySQLChecks, postgreSQLChecks, mongoDBChecks := services.GroupChecksByDB(s.l, checks)
+ mySQLChecks, postgreSQLChecks, mongoDBChecks := groupChecksByDB(s.l, checks)
mySQLChecks = s.filterChecks(mySQLChecks, intervalGroup, disabledChecks, checkNames)
mySQLCheckResults := s.executeChecksForTargetType(ctx, models.MySQLServiceType, mySQLChecks)
- checkResults = append(checkResults, mySQLCheckResults...)
+ res = append(res, mySQLCheckResults...)
postgreSQLChecks = s.filterChecks(postgreSQLChecks, intervalGroup, disabledChecks, checkNames)
postgreSQLCheckResults := s.executeChecksForTargetType(ctx, models.PostgreSQLServiceType, postgreSQLChecks)
- checkResults = append(checkResults, postgreSQLCheckResults...)
+ res = append(res, postgreSQLCheckResults...)
mongoDBChecks = s.filterChecks(mongoDBChecks, intervalGroup, disabledChecks, checkNames)
mongoDBCheckResults := s.executeChecksForTargetType(ctx, models.MongoDBServiceType, mongoDBChecks)
- checkResults = append(checkResults, mongoDBCheckResults...)
+ res = append(res, mongoDBCheckResults...)
- switch {
- case len(checkNames) != 0:
- // If we run some specific checks, delete previous results for them.
- s.alertsRegistry.deleteByName(checkNames)
- case intervalGroup != "":
- // If we run whole interval group, delete previous results for that group.
- s.alertsRegistry.deleteByInterval(intervalGroup)
- default:
- // If we run all checks, delete all previous results.
- s.alertsRegistry.cleanup()
- }
-
- s.alertsRegistry.set(checkResults)
-
- return nil
+ return res, nil
}
func (s *Service) executeChecksForTargetType(ctx context.Context, serviceType models.ServiceType, checks map[string]check.Check) []services.CheckResult {
@@ -767,8 +673,10 @@ func (s *Service) executeChecksForTargetType(ctx context.Context, serviceType mo
s.mChecksExecuted.WithLabelValues(string(target.ServiceType), c.Advisor, c.Name, "error").Inc()
continue
}
- s.mChecksExecuted.WithLabelValues(string(target.ServiceType), c.Advisor, c.Name, "ok").Inc()
+
res = append(res, results...)
+
+ s.mChecksExecuted.WithLabelValues(string(target.ServiceType), c.Advisor, c.Name, "ok").Inc()
}
}
@@ -1689,7 +1597,7 @@ func (s *Service) refreshChecksInMemoryMetric() {
return
}
s.mChecksAvailable.Reset()
- mySQLChecks, postgreSQLChecks, mongoDBChecks := services.GroupChecksByDB(s.l, checks)
+ mySQLChecks, postgreSQLChecks, mongoDBChecks := groupChecksByDB(s.l, checks)
s.incChecksInMemoryMetric(models.MySQLServiceType, mySQLChecks)
s.incChecksInMemoryMetric(models.PostgreSQLServiceType, postgreSQLChecks)
s.incChecksInMemoryMetric(models.MongoDBServiceType, mongoDBChecks)
@@ -1701,6 +1609,27 @@ func (s *Service) incChecksInMemoryMetric(serviceType models.ServiceType, checks
}
}
+// groupChecksByDB splits provided checks by database and returns three slices: for MySQL, for PostgreSQL and for MongoDB.
+func groupChecksByDB(l *logrus.Entry, checks map[string]check.Check) (mySQLChecks, postgreSQLChecks, mongoDBChecks map[string]check.Check) { //nolint:nonamedreturns
+ mySQLChecks = make(map[string]check.Check)
+ postgreSQLChecks = make(map[string]check.Check)
+ mongoDBChecks = make(map[string]check.Check)
+ for _, c := range checks {
+ switch c.GetFamily() {
+ case check.MySQL:
+ mySQLChecks[c.Name] = c
+ case check.PostgreSQL:
+ postgreSQLChecks[c.Name] = c
+ case check.MongoDB:
+ mongoDBChecks[c.Name] = c
+ default:
+ l.Warnf("Unknown check family %s, will be skipped.", c.Family)
+ }
+ }
+
+ return
+}
+
// check interfaces.
var (
_ prom.Collector = (*Service)(nil)
diff --git a/managed/services/checks/checks_test.go b/managed/services/checks/checks_test.go
index 4803f47e37..b38f0b1d4e 100644
--- a/managed/services/checks/checks_test.go
+++ b/managed/services/checks/checks_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -28,14 +28,12 @@ import (
"github.com/percona-platform/saas/pkg/common"
metrics "github.com/prometheus/client_golang/api"
v1 "github.com/prometheus/client_golang/api/prometheus/v1"
- "github.com/prometheus/common/model"
+ "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"gopkg.in/reform.v1"
"gopkg.in/reform.v1/dialects/postgresql"
- "github.com/percona/pmm/api/alertmanager/ammodels"
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services"
"github.com/percona/pmm/managed/utils/platform"
@@ -71,7 +69,7 @@ func TestDownloadAdvisors(t *testing.T) {
platformClient, err := platform.NewClient(db, devPlatformAddress)
require.NoError(t, err)
- s := New(db, platformClient, nil, nil, vmClient, clickhouseDB)
+ s := New(db, platformClient, nil, vmClient, clickhouseDB)
s.platformPublicKeys = []string{devPlatformPublicKey}
require.NoError(t, err)
@@ -120,7 +118,7 @@ func TestDownloadAdvisors(t *testing.T) {
}
func TestLoadLocalChecks(t *testing.T) {
- s := New(nil, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(nil, nil, nil, vmClient, clickhouseDB)
checks, err := s.loadLocalChecks(testChecksFile)
require.NoError(t, err)
@@ -166,7 +164,7 @@ func TestCollectAdvisors(t *testing.T) {
require.NoError(t, err)
t.Run("collect local checks", func(t *testing.T) {
- s := New(db, platformClient, nil, nil, vmClient, clickhouseDB)
+ s := New(db, platformClient, nil, vmClient, clickhouseDB)
s.localChecksFile = testChecksFile
s.CollectAdvisors(context.Background())
@@ -197,7 +195,7 @@ func TestCollectAdvisors(t *testing.T) {
})
t.Run("download checks", func(t *testing.T) {
- s := New(db, platformClient, nil, nil, vmClient, clickhouseDB)
+ s := New(db, platformClient, nil, vmClient, clickhouseDB)
s.platformPublicKeys = []string{devPlatformPublicKey}
s.CollectAdvisors(context.Background())
@@ -230,7 +228,7 @@ func TestDisableChecks(t *testing.T) {
db := reform.NewDB(sqlDB, postgresql.Dialect, nil)
- s := New(db, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
s.localChecksFile = testChecksFile
s.CollectAdvisors(context.Background())
@@ -259,7 +257,7 @@ func TestDisableChecks(t *testing.T) {
db := reform.NewDB(sqlDB, postgresql.Dialect, nil)
- s := New(db, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
s.localChecksFile = testChecksFile
s.CollectAdvisors(context.Background())
@@ -291,7 +289,7 @@ func TestDisableChecks(t *testing.T) {
db := reform.NewDB(sqlDB, postgresql.Dialect, nil)
- s := New(db, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
s.localChecksFile = testChecksFile
s.CollectAdvisors(context.Background())
@@ -314,7 +312,7 @@ func TestEnableChecks(t *testing.T) {
db := reform.NewDB(sqlDB, postgresql.Dialect, nil)
- s := New(db, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
s.localChecksFile = testChecksFile
s.CollectAdvisors(context.Background())
@@ -340,8 +338,6 @@ func TestEnableChecks(t *testing.T) {
func TestChangeInterval(t *testing.T) {
t.Run("normal", func(t *testing.T) {
- var ams mockAlertmanagerService
- ams.On("SendAlerts", mock.Anything, mock.Anything).Return()
sqlDB := testdb.Open(t, models.SkipFixtures, nil)
t.Cleanup(func() {
require.NoError(t, sqlDB.Close())
@@ -349,7 +345,7 @@ func TestChangeInterval(t *testing.T) {
db := reform.NewDB(sqlDB, postgresql.Dialect, nil)
- s := New(db, nil, nil, &ams, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
s.localChecksFile = testChecksFile
s.CollectAdvisors(context.Background())
@@ -394,7 +390,7 @@ func TestGetSecurityCheckResults(t *testing.T) {
db := reform.NewDB(sqlDB, postgresql.Dialect, nil)
t.Run("STT enabled", func(t *testing.T) {
- s := New(db, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
results, err := s.GetSecurityCheckResults()
assert.Empty(t, results)
@@ -402,7 +398,7 @@ func TestGetSecurityCheckResults(t *testing.T) {
})
t.Run("STT disabled", func(t *testing.T) {
- s := New(db, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
settings, err := models.GetSettings(db)
require.NoError(t, err)
@@ -427,7 +423,7 @@ func TestStartChecks(t *testing.T) {
setupClients(t)
t.Run("unknown interval", func(t *testing.T) {
- s := New(db, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
s.localChecksFile = testChecksFile
err := s.runChecksGroup(context.Background(), check.Interval("unknown"))
@@ -435,10 +431,7 @@ func TestStartChecks(t *testing.T) {
})
t.Run("stt enabled", func(t *testing.T) {
- var ams mockAlertmanagerService
- ams.On("SendAlerts", mock.Anything, mock.Anything).Return()
-
- s := New(db, nil, nil, &ams, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
s.localChecksFile = testChecksFile
s.CollectAdvisors(context.Background())
@@ -450,7 +443,7 @@ func TestStartChecks(t *testing.T) {
})
t.Run("stt disabled", func(t *testing.T) {
- s := New(db, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
settings, err := models.GetSettings(db)
require.NoError(t, err)
@@ -540,7 +533,7 @@ func TestFilterChecks(t *testing.T) {
partiallyValidAdvisor.Checks = partiallyValidAdvisor.Checks[0:1] // remove invalid check
expected := append(valid, partiallyValidAdvisor) //nolint:gocritic
- s := New(nil, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(nil, nil, nil, vmClient, clickhouseDB)
actual := s.filterSupportedChecks(checks)
assert.ElementsMatch(t, expected, actual)
}
@@ -565,7 +558,7 @@ func TestMinPMMAgents(t *testing.T) {
{name: "PostgreSQL Family", minVersion: pmmAgent2_6_0, check: check.Check{Version: 2, Queries: []check.Query{{Type: check.PostgreSQLShow}, {Type: check.PostgreSQLSelect}}}},
}
- s := New(nil, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(nil, nil, nil, vmClient, clickhouseDB)
for _, test := range tests {
test := test
@@ -626,7 +619,7 @@ func TestFindTargets(t *testing.T) {
db := reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf))
- s := New(db, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
t.Run("unknown service", func(t *testing.T) {
t.Parallel()
@@ -679,7 +672,7 @@ func TestFindTargets(t *testing.T) {
func TestFilterChecksByInterval(t *testing.T) {
t.Parallel()
- s := New(nil, nil, nil, nil, vmClient, clickhouseDB)
+ s := New(nil, nil, nil, vmClient, clickhouseDB)
rareCheck := check.Check{Name: "rareCheck", Interval: check.Rare}
standardCheck := check.Check{Name: "standardCheck", Interval: check.Standard}
@@ -712,11 +705,7 @@ func TestGetFailedChecks(t *testing.T) {
db := reform.NewDB(sqlDB, postgresql.Dialect, nil)
t.Run("no failed check for service", func(t *testing.T) {
- var ams mockAlertmanagerService
- ctx := context.Background()
- ams.On("GetAlerts", ctx, mock.Anything).Return([]*ammodels.GettableAlert{}, nil)
-
- s := New(db, nil, nil, &ams, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
results, err := s.GetChecksResults(context.Background(), "test_svc")
assert.Empty(t, results)
@@ -724,65 +713,112 @@ func TestGetFailedChecks(t *testing.T) {
})
t.Run("non empty failed checks", func(t *testing.T) {
- alertLabels := map[string]string{
- model.AlertNameLabel: "test_check",
- "alert_id": "test_alert",
- "service_name": "test_svc",
- "service_id": "/service_id/test_svc1",
- "interval_group": "frequent",
- "severity": common.Severity(4).String(),
- }
-
- testAlert := ammodels.GettableAlert{
- Annotations: map[string]string{
- "summary": "Check summary",
- "description": "Check description",
- "read_more_url": "https://www.example.com",
+ checkResults := []services.CheckResult{
+ {
+ CheckName: "test_check",
+ Interval: check.Frequent,
+ Target: services.Target{
+ ServiceName: "test_svc1",
+ ServiceID: "/service_id/test_svc1",
+ Labels: map[string]string{
+ "targetLabel": "targetLabelValue",
+ },
+ },
+ Result: check.Result{
+ Summary: "Check summary",
+ Description: "Check description",
+ ReadMoreURL: "https://www.example.com",
+ Severity: common.Error,
+ Labels: map[string]string{
+ "resultLabel": "reslutLabelValue",
+ },
+ },
},
- Alert: ammodels.Alert{
- Labels: alertLabels,
+ {
+ CheckName: "test_check2",
+ Interval: check.Frequent,
+ Target: services.Target{
+ ServiceName: "test_svc2",
+ ServiceID: "/service_id/test_svc2",
+ Labels: map[string]string{
+ "targetLabel": "targetLabelValue",
+ },
+ },
+ Result: check.Result{
+ Summary: "Check summary",
+ Description: "Check description",
+ ReadMoreURL: "https://www.example.com",
+ Severity: common.Error,
+ Labels: map[string]string{
+ "resultLabel": "reslutLabelValue",
+ },
+ },
},
- Status: &ammodels.AlertStatus{},
}
- results := []services.CheckResult{
+ s := New(db, nil, nil, vmClient, clickhouseDB)
+ s.alertsRegistry.set(checkResults)
+
+ response, err := s.GetChecksResults(context.Background(), "")
+ require.NoError(t, err)
+ assert.ElementsMatch(t, checkResults, response)
+ })
+
+ t.Run("non empty failed checks for specific service", func(t *testing.T) {
+ checkResults := []services.CheckResult{
{
CheckName: "test_check",
- AlertID: "test_alert",
- Silenced: false,
Interval: check.Frequent,
Target: services.Target{
- ServiceName: "test_svc",
+ ServiceName: "test_svc1",
ServiceID: "/service_id/test_svc1",
- Labels: alertLabels,
+ Labels: map[string]string{
+ "targetLabel": "targetLabelValue",
+ },
+ },
+ Result: check.Result{
+ Summary: "Check summary",
+ Description: "Check description",
+ ReadMoreURL: "https://www.example.com",
+ Severity: common.Error,
+ Labels: map[string]string{
+ "resultLabel": "reslutLabelValue",
+ },
+ },
+ },
+ {
+ CheckName: "test_check2",
+ Interval: check.Frequent,
+ Target: services.Target{
+ ServiceName: "test_svc2",
+ ServiceID: "/service_id/test_svc2",
+ Labels: map[string]string{
+ "targetLabel": "targetLabelValue",
+ },
},
Result: check.Result{
Summary: "Check summary",
Description: "Check description",
ReadMoreURL: "https://www.example.com",
Severity: common.Error,
- Labels: alertLabels,
+ Labels: map[string]string{
+ "resultLabel": "reslutLabelValue",
+ },
},
},
}
- ams := mockAlertmanagerService{}
- ctx := context.Background()
- ams.On("GetAlerts", ctx, mock.Anything).Return([]*ammodels.GettableAlert{&testAlert}, nil)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
+ s.alertsRegistry.set(checkResults)
- s := New(db, nil, nil, &ams, vmClient, clickhouseDB)
-
- response, err := s.GetChecksResults(ctx, "test_svc")
+ response, err := s.GetChecksResults(context.Background(), "/service_id/test_svc1")
require.NoError(t, err)
- assert.Equal(t, results, response)
+ require.Len(t, response, 1)
+ assert.Equal(t, checkResults[0], response[0])
})
t.Run("STT disabled", func(t *testing.T) {
- ams := mockAlertmanagerService{}
- ctx := context.Background()
- ams.On("GetAlerts", ctx, mock.Anything).Return(nil, services.ErrAdvisorsDisabled)
-
- s := New(db, nil, nil, &ams, vmClient, clickhouseDB)
+ s := New(db, nil, nil, vmClient, clickhouseDB)
settings, err := models.GetSettings(db)
require.NoError(t, err)
@@ -791,66 +827,12 @@ func TestGetFailedChecks(t *testing.T) {
err = models.SaveSettings(db, settings)
require.NoError(t, err)
- results, err := s.GetChecksResults(ctx, "test_svc")
+ results, err := s.GetChecksResults(context.Background(), "test_svc")
assert.Nil(t, results)
assert.ErrorIs(t, err, services.ErrAdvisorsDisabled)
})
}
-func TestToggleCheckAlert(t *testing.T) {
- t.Parallel()
-
- t.Run("silence alert", func(t *testing.T) {
- t.Parallel()
-
- testAlert := &ammodels.GettableAlert{
- Alert: ammodels.Alert{
- Labels: map[string]string{
- "alert_id": "test_alert_1",
- },
- },
- Status: &ammodels.AlertStatus{},
- }
-
- var ams mockAlertmanagerService
- ctx := context.Background()
- ams.On("GetAlerts", ctx, mock.Anything).Return([]*ammodels.GettableAlert{testAlert}, nil)
- ams.On("SilenceAlerts", ctx, []*ammodels.GettableAlert{testAlert}).Return(nil)
-
- s := New(nil, nil, nil, &ams, vmClient, clickhouseDB)
-
- active := len(testAlert.Status.SilencedBy) == 0
- err := s.ToggleCheckAlert(ctx, "test_alert_1", active)
- require.NoError(t, err)
- ams.AssertCalled(t, "SilenceAlerts", ctx, []*ammodels.GettableAlert{testAlert})
- })
-
- t.Run("unsilence alert", func(t *testing.T) {
- t.Parallel()
-
- testAlert := &ammodels.GettableAlert{
- Alert: ammodels.Alert{
- Labels: map[string]string{
- "alert_id": "test_alert_2",
- },
- },
- Status: &ammodels.AlertStatus{SilencedBy: []string{"test_silence"}},
- }
-
- var ams mockAlertmanagerService
- ctx := context.Background()
- ams.On("GetAlerts", ctx, mock.Anything).Return([]*ammodels.GettableAlert{testAlert}, nil)
- ams.On("UnsilenceAlerts", ctx, []*ammodels.GettableAlert{testAlert}).Return(nil)
-
- s := New(nil, nil, nil, &ams, vmClient, clickhouseDB)
-
- active := len(testAlert.Status.SilencedBy) == 0
- err := s.ToggleCheckAlert(ctx, "test_alert_1", active)
- require.NoError(t, err)
- ams.AssertCalled(t, "UnsilenceAlerts", ctx, []*ammodels.GettableAlert{testAlert})
- })
-}
-
func TestFillQueryPlaceholders(t *testing.T) {
t.Parallel()
@@ -929,3 +911,50 @@ func TestFillQueryPlaceholders(t *testing.T) {
})
}
}
+
+func TestGroupChecksByDB(t *testing.T) {
+ t.Parallel()
+
+ checks := map[string]check.Check{
+ "MySQLShow": {Name: "MySQLShow", Version: 1, Type: check.MySQLShow},
+ "MySQLSelect": {Name: "MySQLSelect", Version: 1, Type: check.MySQLSelect},
+ "PostgreSQLShow": {Name: "PostgreSQLShow", Version: 1, Type: check.PostgreSQLShow},
+ "PostgreSQLSelect": {Name: "PostgreSQLSelect", Version: 1, Type: check.PostgreSQLSelect},
+ "MongoDBGetParameter": {Name: "MongoDBGetParameter", Version: 1, Type: check.MongoDBGetParameter},
+ "MongoDBBuildInfo": {Name: "MongoDBBuildInfo", Version: 1, Type: check.MongoDBBuildInfo},
+ "MongoDBGetCmdLineOpts": {Name: "MongoDBGetCmdLineOpts", Version: 1, Type: check.MongoDBGetCmdLineOpts},
+ "MongoDBReplSetGetStatus": {Name: "MongoDBReplSetGetStatus", Version: 1, Type: check.MongoDBReplSetGetStatus},
+ "MongoDBGetDiagnosticData": {Name: "MongoDBGetDiagnosticData", Version: 1, Type: check.MongoDBGetDiagnosticData},
+ "unsupported type": {Name: "unsupported type", Version: 1, Type: check.Type("RedisInfo")},
+ "missing type": {Name: "missing type", Version: 1},
+ "MySQL family V2": {Name: "MySQL family V2", Version: 2, Family: check.MySQL},
+ "PostgreSQL family V2": {Name: "PostgreSQL family V2", Version: 2, Family: check.PostgreSQL},
+ "MongoDB family V2": {Name: "MongoDB family V2", Version: 2, Family: check.MongoDB},
+ "missing family": {Name: "missing family", Version: 2},
+ }
+
+ l := logrus.WithField("component", "tests")
+ mySQLChecks, postgreSQLChecks, mongoDBChecks := groupChecksByDB(l, checks)
+
+ require.Len(t, mySQLChecks, 3)
+ require.Len(t, postgreSQLChecks, 3)
+ require.Len(t, mongoDBChecks, 6)
+
+ // V1 checks
+ assert.Equal(t, check.MySQLShow, mySQLChecks["MySQLShow"].Type)
+ assert.Equal(t, check.MySQLSelect, mySQLChecks["MySQLSelect"].Type)
+
+ assert.Equal(t, check.PostgreSQLShow, postgreSQLChecks["PostgreSQLShow"].Type)
+ assert.Equal(t, check.PostgreSQLSelect, postgreSQLChecks["PostgreSQLSelect"].Type)
+
+ assert.Equal(t, check.MongoDBGetParameter, mongoDBChecks["MongoDBGetParameter"].Type)
+ assert.Equal(t, check.MongoDBBuildInfo, mongoDBChecks["MongoDBBuildInfo"].Type)
+ assert.Equal(t, check.MongoDBGetCmdLineOpts, mongoDBChecks["MongoDBGetCmdLineOpts"].Type)
+ assert.Equal(t, check.MongoDBReplSetGetStatus, mongoDBChecks["MongoDBReplSetGetStatus"].Type)
+ assert.Equal(t, check.MongoDBGetDiagnosticData, mongoDBChecks["MongoDBGetDiagnosticData"].Type)
+
+ // V2 checks
+ assert.Equal(t, check.MySQL, mySQLChecks["MySQL family V2"].Family)
+ assert.Equal(t, check.PostgreSQL, postgreSQLChecks["PostgreSQL family V2"].Family)
+ assert.Equal(t, check.MongoDB, mongoDBChecks["MongoDB family V2"].Family)
+}
diff --git a/managed/services/checks/deps.go b/managed/services/checks/deps.go
index d4b3feeccb..8e9912ba16 100644
--- a/managed/services/checks/deps.go
+++ b/managed/services/checks/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -18,13 +18,10 @@ package checks
import (
"context"
- "github.com/percona/pmm/api/alertmanager/ammodels"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/services"
)
//go:generate ../../../bin/mockery --name=agentsRegistry --case=snake --inpackage --testonly
-//go:generate ../../../bin/mockery --name=alertmanagerService --case=snake --inpackage --testonly
// agentsRegistry is a subset of methods of agents.Registry used by this package.
// We use it instead of real type for testing and to avoid dependency cycle.
@@ -39,12 +36,3 @@ type agentsRegistry interface {
StartMongoDBQueryReplSetGetStatusAction(ctx context.Context, id, pmmAgentID, dsn string, files map[string]string, tdp *models.DelimiterPair) error
StartMongoDBQueryGetDiagnosticDataAction(ctx context.Context, id, pmmAgentID, dsn string, files map[string]string, tdp *models.DelimiterPair) error
}
-
-// alertmanagerService is a subset of methods of alertmanager.Service used by this package.
-// We use it instead of real type for testing and to avoid dependency cycle.
-type alertmanagerService interface {
- SendAlerts(ctx context.Context, alerts ammodels.PostableAlerts)
- SilenceAlerts(ctx context.Context, alerts []*ammodels.GettableAlert) error
- UnsilenceAlerts(ctx context.Context, alerts []*ammodels.GettableAlert) error
- GetAlerts(ctx context.Context, params *services.FilterParams) ([]*ammodels.GettableAlert, error)
-}
diff --git a/managed/services/checks/funcs.go b/managed/services/checks/funcs.go
index 29927f4832..aa046777d5 100644
--- a/managed/services/checks/funcs.go
+++ b/managed/services/checks/funcs.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/checks/funcs_test.go b/managed/services/checks/funcs_test.go
index 2212e34e6f..2723d4e8c8 100644
--- a/managed/services/checks/funcs_test.go
+++ b/managed/services/checks/funcs_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/checks/mock_agents_registry_test.go b/managed/services/checks/mock_agents_registry_test.go
index 4783d9703e..e57b3fdfd5 100644
--- a/managed/services/checks/mock_agents_registry_test.go
+++ b/managed/services/checks/mock_agents_registry_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package checks
diff --git a/managed/services/checks/mock_alertmanager_service_test.go b/managed/services/checks/mock_alertmanager_service_test.go
deleted file mode 100644
index 0b3c450ce2..0000000000
--- a/managed/services/checks/mock_alertmanager_service_test.go
+++ /dev/null
@@ -1,91 +0,0 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
-
-package checks
-
-import (
- context "context"
-
- mock "github.com/stretchr/testify/mock"
-
- ammodels "github.com/percona/pmm/api/alertmanager/ammodels"
- services "github.com/percona/pmm/managed/services"
-)
-
-// mockAlertmanagerService is an autogenerated mock type for the alertmanagerService type
-type mockAlertmanagerService struct {
- mock.Mock
-}
-
-// GetAlerts provides a mock function with given fields: ctx, params
-func (_m *mockAlertmanagerService) GetAlerts(ctx context.Context, params *services.FilterParams) ([]*ammodels.GettableAlert, error) {
- ret := _m.Called(ctx, params)
-
- var r0 []*ammodels.GettableAlert
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, *services.FilterParams) ([]*ammodels.GettableAlert, error)); ok {
- return rf(ctx, params)
- }
- if rf, ok := ret.Get(0).(func(context.Context, *services.FilterParams) []*ammodels.GettableAlert); ok {
- r0 = rf(ctx, params)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).([]*ammodels.GettableAlert)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, *services.FilterParams) error); ok {
- r1 = rf(ctx, params)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// SendAlerts provides a mock function with given fields: ctx, alerts
-func (_m *mockAlertmanagerService) SendAlerts(ctx context.Context, alerts ammodels.PostableAlerts) {
- _m.Called(ctx, alerts)
-}
-
-// SilenceAlerts provides a mock function with given fields: ctx, alerts
-func (_m *mockAlertmanagerService) SilenceAlerts(ctx context.Context, alerts []*ammodels.GettableAlert) error {
- ret := _m.Called(ctx, alerts)
-
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, []*ammodels.GettableAlert) error); ok {
- r0 = rf(ctx, alerts)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// UnsilenceAlerts provides a mock function with given fields: ctx, alerts
-func (_m *mockAlertmanagerService) UnsilenceAlerts(ctx context.Context, alerts []*ammodels.GettableAlert) error {
- ret := _m.Called(ctx, alerts)
-
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, []*ammodels.GettableAlert) error); ok {
- r0 = rf(ctx, alerts)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// newMockAlertmanagerService creates a new instance of mockAlertmanagerService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func newMockAlertmanagerService(t interface {
- mock.TestingT
- Cleanup(func())
-},
-) *mockAlertmanagerService {
- mock := &mockAlertmanagerService{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/managed/services/checks/registry.go b/managed/services/checks/registry.go
index b357de660a..1ccb42932c 100644
--- a/managed/services/checks/registry.go
+++ b/managed/services/checks/registry.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -16,18 +16,11 @@
package checks
import (
- "crypto/sha1" //nolint:gosec
- "encoding/hex"
- "fmt"
"sync"
- "time"
- "github.com/go-openapi/strfmt"
"github.com/percona-platform/saas/pkg/check"
prom "github.com/prometheus/client_golang/prometheus"
- "github.com/prometheus/common/model"
- "github.com/percona/pmm/api/alertmanager/ammodels"
"github.com/percona/pmm/managed/services"
)
@@ -36,20 +29,13 @@ type registry struct {
rw sync.RWMutex
// Results stored grouped by interval and by check name. It allows us to remove results for specific group.
checkResults map[check.Interval]map[string][]services.CheckResult
-
- alertTTL time.Duration
- nowF func() time.Time // for tests
-
- mInsights *prom.GaugeVec
+ mInsights *prom.GaugeVec
}
// newRegistry creates a new registry.
-func newRegistry(alertTTL time.Duration) *registry {
+func newRegistry() *registry {
return ®istry{
checkResults: make(map[check.Interval]map[string][]services.CheckResult),
- alertTTL: alertTTL,
- nowF: time.Now,
-
mInsights: prom.NewGaugeVec(prom.GaugeOpts{
Namespace: prometheusNamespace,
Subsystem: prometheusSubsystem,
@@ -105,70 +91,25 @@ func (r *registry) cleanup() {
r.checkResults = make(map[check.Interval]map[string][]services.CheckResult)
}
-// collect returns a slice of alerts created from the stored check results.
-func (r *registry) collect() ammodels.PostableAlerts {
+// getCheckResults returns checks results for the given service. If serviceID is empty it returns results for all services.
+func (r *registry) getCheckResults(serviceID string) []services.CheckResult {
r.rw.RLock()
defer r.rw.RUnlock()
- var alerts ammodels.PostableAlerts
+ var results []services.CheckResult
for _, intervalGroup := range r.checkResults {
for _, checkNameGroup := range intervalGroup {
for _, checkResult := range checkNameGroup {
- checkResult := checkResult
- alerts = append(alerts, r.createAlert(&checkResult))
+ if serviceID == "" || checkResult.Target.ServiceID == serviceID {
+ results = append(results, checkResult)
+ }
}
}
}
- return alerts
-}
-
-func (r *registry) getCheckResults() []services.CheckResult {
- r.rw.RLock()
- defer r.rw.RUnlock()
-
- var results []services.CheckResult
- for _, intervalGroup := range r.checkResults {
- for _, checkNameGroup := range intervalGroup {
- results = append(results, checkNameGroup...)
- }
- }
return results
}
-func (r *registry) createAlert(checkResult *services.CheckResult) *ammodels.PostableAlert {
- name, target, result, alertTTL := checkResult.CheckName, &checkResult.Target, &checkResult.Result, r.alertTTL
- labels := make(map[string]string, len(target.Labels)+len(result.Labels)+4)
- annotations := make(map[string]string, 2)
- for k, v := range result.Labels {
- labels[k] = v
- }
- for k, v := range target.Labels {
- labels[k] = v
- }
-
- labels[model.AlertNameLabel] = name
- checkResult.AlertID = makeID(target, result)
- labels["severity"] = result.Severity.String()
- labels["stt_check"] = "1"
- labels["alert_id"] = checkResult.AlertID
- labels["interval_group"] = string(checkResult.Interval)
-
- annotations["summary"] = result.Summary
- annotations["description"] = result.Description
- annotations["read_more_url"] = result.ReadMoreURL
-
- endsAt := r.nowF().Add(alertTTL).UTC().Round(0) // strip a monotonic clock reading
- return &ammodels.PostableAlert{
- Alert: ammodels.Alert{
- // GeneratorURL: "TODO",
- Labels: labels,
- },
- EndsAt: strfmt.DateTime(endsAt),
- Annotations: annotations,
- }
-}
-
// Describe implements prom.Collector.
func (r *registry) Describe(ch chan<- *prom.Desc) {
r.mInsights.Describe(ch)
@@ -177,21 +118,9 @@ func (r *registry) Describe(ch chan<- *prom.Desc) {
// Collect implements prom.Collector.
func (r *registry) Collect(ch chan<- prom.Metric) {
r.mInsights.Reset()
- res := r.getCheckResults()
+ res := r.getCheckResults("")
for _, re := range res {
r.mInsights.WithLabelValues(string(re.Target.ServiceType), re.AdvisorName, re.CheckName).Inc()
}
r.mInsights.Collect(ch)
}
-
-// makeID creates an ID for STT check alert.
-func makeID(target *services.Target, result *check.Result) string {
- s := sha1.New() //nolint:gosec
- fmt.Fprintf(s, "%s\n", target.AgentID)
- fmt.Fprintf(s, "%s\n", target.ServiceID)
- fmt.Fprintf(s, "%s\n", result.Summary)
- fmt.Fprintf(s, "%s\n", result.Description)
- fmt.Fprintf(s, "%s\n", result.ReadMoreURL)
- fmt.Fprintf(s, "%v\n", result.Severity)
- return alertsPrefix + hex.EncodeToString(s.Sum(nil))
-}
diff --git a/managed/services/checks/registry_test.go b/managed/services/checks/registry_test.go
index 0b4ca97e9b..6ef6d1d26a 100644
--- a/managed/services/checks/registry_test.go
+++ b/managed/services/checks/registry_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -17,25 +17,18 @@ package checks
import (
"testing"
- "time"
- "github.com/go-openapi/strfmt"
"github.com/percona-platform/saas/pkg/check"
"github.com/percona-platform/saas/pkg/common"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- "github.com/percona/pmm/api/alertmanager/ammodels"
"github.com/percona/pmm/managed/services"
)
func TestRegistry(t *testing.T) {
t.Run("create and collect Alerts", func(t *testing.T) {
- alertTTL := resolveTimeoutFactor * defaultResendInterval
- r := newRegistry(alertTTL)
-
- nowValue := time.Now().UTC().Round(0) // strip a monotonic clock reading
- r.nowF = func() time.Time { return nowValue }
+ r := newRegistry()
checkResults := []services.CheckResult{
{
CheckName: "name",
@@ -80,57 +73,15 @@ func TestRegistry(t *testing.T) {
r.set(checkResults)
- expectedAlerts := []*ammodels.PostableAlert{
- {
- Annotations: map[string]string{
- "summary": "check summary",
- "description": "check description",
- "read_more_url": "https://www.example.com",
- },
- EndsAt: strfmt.DateTime(nowValue.Add(alertTTL)),
- Alert: ammodels.Alert{
- Labels: map[string]string{
- "alert_id": "/stt/e7b471407fe9734eac5b6adb178ee0ef08ef45f2",
- "alertname": "name",
- "baz": "qux",
- "foo": "bar",
- "severity": "warning",
- "stt_check": "1",
- "interval_group": string(check.Standard),
- },
- },
- },
- {
- Annotations: map[string]string{
- "summary": "check summary 2",
- "description": "check description 2",
- "read_more_url": "https://www.example2.com",
- },
- EndsAt: strfmt.DateTime(nowValue.Add(alertTTL)),
- Alert: ammodels.Alert{
- Labels: map[string]string{
- "alert_id": "/stt/8fa5695dc34160333eeeb05f00bf1ddbd98be59c",
- "alertname": "name2",
- "qux": "baz",
- "bar": "foo",
- "severity": "notice",
- "stt_check": "1",
- "interval_group": string(check.Standard),
- },
- },
- },
- }
+ // Empty interval means standard
+ checkResults[1].Interval = check.Standard
- collectedAlerts := r.collect()
- assert.ElementsMatch(t, expectedAlerts, collectedAlerts)
+ collectedAlerts := r.getCheckResults("")
+ assert.ElementsMatch(t, checkResults, collectedAlerts)
})
t.Run("delete check results by interval", func(t *testing.T) {
- alertTTL := resolveTimeoutFactor * defaultResendInterval
- r := newRegistry(alertTTL)
-
- nowValue := time.Now().UTC().Round(0) // strip a monotonic clock reading
- r.nowF = func() time.Time { return nowValue }
+ r := newRegistry()
checkResults := []services.CheckResult{
{
CheckName: "name",
@@ -177,40 +128,17 @@ func TestRegistry(t *testing.T) {
r.set(checkResults)
r.deleteByInterval(check.Standard)
- expectedAlert := &ammodels.PostableAlert{
- Annotations: map[string]string{
- "summary": "check summary 2",
- "description": "check description 2",
- "read_more_url": "https://www.example2.com",
- },
- EndsAt: strfmt.DateTime(nowValue.Add(alertTTL)),
- Alert: ammodels.Alert{
- Labels: map[string]string{
- "alert_id": "/stt/8fa5695dc34160333eeeb05f00bf1ddbd98be59c",
- "alertname": "name2",
- "qux": "baz",
- "bar": "foo",
- "severity": "notice",
- "stt_check": "1",
- "interval_group": string(check.Frequent),
- },
- },
- }
-
- collectedAlerts := r.collect()
+ collectedAlerts := r.getCheckResults("")
require.Len(t, collectedAlerts, 1)
- assert.Equal(t, expectedAlert, collectedAlerts[0])
+ assert.Equal(t, checkResults[1], collectedAlerts[0])
})
t.Run("delete check result by name", func(t *testing.T) {
- alertTTL := resolveTimeoutFactor * defaultResendInterval
- r := newRegistry(alertTTL)
-
- nowValue := time.Now().UTC().Round(0) // strip a monotonic clock reading
- r.nowF = func() time.Time { return nowValue }
+ r := newRegistry()
checkResults := []services.CheckResult{
{
CheckName: "name1",
+ Interval: check.Standard,
Target: services.Target{
AgentID: "/agent_id/123",
ServiceID: "/service_id/123",
@@ -230,6 +158,7 @@ func TestRegistry(t *testing.T) {
},
{
CheckName: "name2",
+ Interval: check.Standard,
Target: services.Target{
AgentID: "/agent_id/321",
ServiceID: "/service_id/321",
@@ -252,37 +181,13 @@ func TestRegistry(t *testing.T) {
r.set(checkResults)
r.deleteByName([]string{"name1"})
- expectedAlert := &ammodels.PostableAlert{
- Annotations: map[string]string{
- "summary": "check summary 2",
- "description": "check description 2",
- "read_more_url": "https://www.example2.com",
- },
- EndsAt: strfmt.DateTime(nowValue.Add(alertTTL)),
- Alert: ammodels.Alert{
- Labels: map[string]string{
- "alert_id": "/stt/8fa5695dc34160333eeeb05f00bf1ddbd98be59c",
- "alertname": "name2",
- "qux": "baz",
- "bar": "foo",
- "severity": "notice",
- "stt_check": "1",
- "interval_group": string(check.Standard),
- },
- },
- }
-
- collectedAlerts := r.collect()
+ collectedAlerts := r.getCheckResults("")
require.Len(t, collectedAlerts, 1)
- assert.Equal(t, expectedAlert, collectedAlerts[0])
+ assert.Equal(t, checkResults[1], collectedAlerts[0])
})
t.Run("empty interval recognized as standard", func(t *testing.T) {
- alertTTL := resolveTimeoutFactor * defaultResendInterval
- r := newRegistry(alertTTL)
-
- nowValue := time.Now().UTC().Round(0) // strip a monotonic clock reading
- r.nowF = func() time.Time { return nowValue }
+ r := newRegistry()
checkResults := []services.CheckResult{
{
CheckName: "name",
@@ -328,7 +233,7 @@ func TestRegistry(t *testing.T) {
r.set(checkResults)
r.deleteByInterval(check.Standard)
- collectedAlerts := r.collect()
+ collectedAlerts := r.getCheckResults("")
assert.Empty(t, collectedAlerts)
})
}
diff --git a/managed/services/config/config.go b/managed/services/config/config.go
index c8637bd278..da63fa58e7 100644
--- a/managed/services/config/config.go
+++ b/managed/services/config/config.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/config/pmm-managed.yaml b/managed/services/config/pmm-managed.yaml
index af40bfc254..d9341b020f 100644
--- a/managed/services/config/pmm-managed.yaml
+++ b/managed/services/config/pmm-managed.yaml
@@ -6,7 +6,6 @@ services:
VM:
enabled: true
timeout: 2s
- address: http://localhost:9090/prometheus
QANDB_SELECT:
enabled: true
timeout: 2s
diff --git a/managed/services/converters.go b/managed/services/converters.go
index edfcf3f4e9..a4da1283f0 100644
--- a/managed/services/converters.go
+++ b/managed/services/converters.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -475,7 +475,7 @@ func ToAPIAgent(q *reform.Querier, agent *models.Agent) (inventorypb.Agent, erro
}
// SpecifyLogLevel - convert proto enum to string
-// mysqld_exporter, node_exporter and postgres_exporter don't support --log.level=fatal
+// mysqld_exporter, node_exporter and postgres_exporter don't support --log.level=fatal.
func SpecifyLogLevel(variant, minLogLevel inventorypb.LogLevel) string {
if variant == inventorypb.LogLevel_auto {
return ""
diff --git a/managed/services/dbaas/dbaas_client.go b/managed/services/dbaas/dbaas_client.go
index 2e3ec415f6..2768eea2b1 100644
--- a/managed/services/dbaas/dbaas_client.go
+++ b/managed/services/dbaas/dbaas_client.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/dbaas/kubernetes/client/client.go b/managed/services/dbaas/kubernetes/client/client.go
index 309887ee9f..832023e00b 100644
--- a/managed/services/dbaas/kubernetes/client/client.go
+++ b/managed/services/dbaas/kubernetes/client/client.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-// Package client TODO
+// Package client TODO.
package client
import (
@@ -107,7 +107,7 @@ type Client struct {
namespace string
}
-// SortableEvents implements sort.Interface for []api.Event based on the Timestamp field
+// SortableEvents implements sort.Interface for []api.Event based on the Timestamp field.
type SortableEvents []corev1.Event
func (list SortableEvents) Len() int {
@@ -192,7 +192,7 @@ func NewFromInCluster() (*Client, error) {
}
// NewFromKubeConfigString creates a new client for the given config string.
-// It's intended for clients that expect to be running outside of a cluster
+// It's intended for clients that expect to be running outside of a cluster.
func NewFromKubeConfigString(kubeconfig string) (*Client, error) {
config, err := clientcmd.BuildConfigFromKubeconfigGetter("", NewConfigGetter(kubeconfig).loadFromString)
if err != nil {
@@ -235,7 +235,7 @@ func (c *Client) setup() error {
return c.initOperatorClients()
}
-// Initializes clients for operators
+// Initializes clients for operators.
func (c *Client) initOperatorClients() error {
dbClusterClient, err := database.NewForConfig(c.restConfig)
if err != nil {
@@ -246,7 +246,7 @@ func (c *Client) initOperatorClients() error {
return err
}
-// GetSecretsForServiceAccount returns secret by given service account name
+// GetSecretsForServiceAccount returns secret by given service account name.
func (c *Client) GetSecretsForServiceAccount(ctx context.Context, accountName string) (*corev1.Secret, error) {
serviceAccount, err := c.clientset.CoreV1().ServiceAccounts(c.namespace).Get(ctx, accountName, metav1.GetOptions{})
if err != nil {
@@ -263,7 +263,7 @@ func (c *Client) GetSecretsForServiceAccount(ctx context.Context, accountName st
metav1.GetOptions{})
}
-// GenerateKubeConfig generates kubeconfig
+// GenerateKubeConfig generates kubeconfig.
func (c *Client) GenerateKubeConfig(secret *corev1.Secret) ([]byte, error) {
conf := &Config{
Kind: configKind,
@@ -301,7 +301,7 @@ func (c *Client) GenerateKubeConfig(secret *corev1.Secret) ([]byte, error) {
return c.marshalKubeConfig(conf)
}
-// GetServerVersion returns server version
+// GetServerVersion returns server version.
func (c *Client) GetServerVersion() (*version.Info, error) {
return c.clientset.Discovery().ServerVersion()
}
@@ -320,27 +320,27 @@ func (c *Client) GetDatabaseCluster(ctx context.Context, name string) (*dbaasv1.
return cluster, nil
}
-// GetStorageClasses returns all storage classes available in the cluster
+// GetStorageClasses returns all storage classes available in the cluster.
func (c *Client) GetStorageClasses(ctx context.Context) (*storagev1.StorageClassList, error) {
return c.clientset.StorageV1().StorageClasses().List(ctx, metav1.ListOptions{})
}
-// GetDeployment returns deployment by name
+// GetDeployment returns deployment by name.
func (c *Client) GetDeployment(ctx context.Context, name string) (*appsv1.Deployment, error) {
return c.clientset.AppsV1().Deployments(c.namespace).Get(ctx, name, metav1.GetOptions{})
}
-// GetSecret returns secret by name
+// GetSecret returns secret by name.
func (c *Client) GetSecret(ctx context.Context, name string) (*corev1.Secret, error) {
return c.clientset.CoreV1().Secrets(c.namespace).Get(ctx, name, metav1.GetOptions{})
}
-// ListSecrets returns secrets
+// ListSecrets returns secrets.
func (c *Client) ListSecrets(ctx context.Context) (*corev1.SecretList, error) {
return c.clientset.CoreV1().Secrets(c.namespace).List(ctx, metav1.ListOptions{})
}
-// DeleteObject deletes object from the k8s cluster
+// DeleteObject deletes object from the k8s cluster.
func (c *Client) DeleteObject(obj runtime.Object) error {
groupResources, err := restmapper.GetAPIGroupResources(c.clientset.Discovery())
if err != nil {
@@ -459,12 +459,12 @@ func (c *Client) marshalKubeConfig(conf *Config) ([]byte, error) {
return yaml.Marshal(jsonObj)
}
-// GetPersistentVolumes returns Persistent Volumes available in the cluster
+// GetPersistentVolumes returns Persistent Volumes available in the cluster.
func (c *Client) GetPersistentVolumes(ctx context.Context) (*corev1.PersistentVolumeList, error) {
return c.clientset.CoreV1().PersistentVolumes().List(ctx, metav1.ListOptions{})
}
-// GetPods returns list of pods
+// GetPods returns list of pods.
func (c *Client) GetPods(ctx context.Context, namespace string, labelSelector *metav1.LabelSelector) (*corev1.PodList, error) {
options := metav1.ListOptions{}
if labelSelector != nil && (labelSelector.MatchLabels != nil || labelSelector.MatchExpressions != nil) {
@@ -474,12 +474,12 @@ func (c *Client) GetPods(ctx context.Context, namespace string, labelSelector *m
return c.clientset.CoreV1().Pods(namespace).List(ctx, options)
}
-// GetNodes returns list of nodes
+// GetNodes returns list of nodes.
func (c *Client) GetNodes(ctx context.Context) (*corev1.NodeList, error) {
return c.clientset.CoreV1().Nodes().List(ctx, metav1.ListOptions{})
}
-// GetLogs returns logs for pod
+// GetLogs returns logs for pod.
func (c *Client) GetLogs(ctx context.Context, pod, container string) (string, error) {
defaultLogLines := int64(3000)
options := &corev1.PodLogOptions{}
@@ -671,7 +671,7 @@ func translateTimestampSince(timestamp metav1.Time) string {
}
// ApplyFile accepts manifest file contents, parses into []runtime.Object
-// and applies them against the cluster
+// and applies them against the cluster.
func (c *Client) ApplyFile(fileBytes []byte) error {
objs, err := c.getObjects(fileBytes)
if err != nil {
diff --git a/managed/services/dbaas/kubernetes/client/client_test.go b/managed/services/dbaas/kubernetes/client/client_test.go
index 542fa2b927..6bcdcf0e62 100644
--- a/managed/services/dbaas/kubernetes/client/client_test.go
+++ b/managed/services/dbaas/kubernetes/client/client_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/dbaas/kubernetes/client/ctl.go b/managed/services/dbaas/kubernetes/client/ctl.go
index 795f0863f9..a3081c35bb 100644
--- a/managed/services/dbaas/kubernetes/client/ctl.go
+++ b/managed/services/dbaas/kubernetes/client/ctl.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/dbaas/kubernetes/client/database/database.go b/managed/services/dbaas/kubernetes/client/database/database.go
index f803a10e72..b332f0f1e9 100644
--- a/managed/services/dbaas/kubernetes/client/database/database.go
+++ b/managed/services/dbaas/kubernetes/client/database/database.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-// Package database TODO
+// Package database TODO.
package database
import (
diff --git a/managed/services/dbaas/kubernetes/client/gen.go b/managed/services/dbaas/kubernetes/client/gen.go
index fe733886cf..1b9eddf585 100644
--- a/managed/services/dbaas/kubernetes/client/gen.go
+++ b/managed/services/dbaas/kubernetes/client/gen.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/dbaas/kubernetes/client/kubeclient_interface.go b/managed/services/dbaas/kubernetes/client/kubeclient_interface.go
index e64a80225e..4a258117c6 100644
--- a/managed/services/dbaas/kubernetes/client/kubeclient_interface.go
+++ b/managed/services/dbaas/kubernetes/client/kubeclient_interface.go
@@ -23,38 +23,38 @@ import (
// KubeClientConnector ...
type KubeClientConnector interface {
- // GetSecretsForServiceAccount returns secret by given service account name
+ // GetSecretsForServiceAccount returns secret by given service account name.
GetSecretsForServiceAccount(ctx context.Context, accountName string) (*corev1.Secret, error)
- // GenerateKubeConfig generates kubeconfig
+ // GenerateKubeConfig generates kubeconfig.
GenerateKubeConfig(secret *corev1.Secret) ([]byte, error)
- // GetServerVersion returns server version
+ // GetServerVersion returns server version.
GetServerVersion() (*version.Info, error)
// ListDatabaseClusters returns list of managed PCX clusters.
ListDatabaseClusters(ctx context.Context) (*dbaasv1.DatabaseClusterList, error)
// GetDatabaseCluster returns PXC clusters by provided name.
GetDatabaseCluster(ctx context.Context, name string) (*dbaasv1.DatabaseCluster, error)
- // GetStorageClasses returns all storage classes available in the cluster
+ // GetStorageClasses returns all storage classes available in the cluster.
GetStorageClasses(ctx context.Context) (*storagev1.StorageClassList, error)
- // GetDeployment returns deployment by name
+ // GetDeployment returns deployment by name.
GetDeployment(ctx context.Context, name string) (*appsv1.Deployment, error)
- // GetSecret returns secret by name
+ // GetSecret returns secret by name.
GetSecret(ctx context.Context, name string) (*corev1.Secret, error)
- // ListSecrets returns secrets
+ // ListSecrets returns secrets.
ListSecrets(ctx context.Context) (*corev1.SecretList, error)
- // DeleteObject deletes object from the k8s cluster
+ // DeleteObject deletes object from the k8s cluster.
DeleteObject(obj runtime.Object) error
ApplyObject(obj runtime.Object) error
- // GetPersistentVolumes returns Persistent Volumes available in the cluster
+ // GetPersistentVolumes returns Persistent Volumes available in the cluster.
GetPersistentVolumes(ctx context.Context) (*corev1.PersistentVolumeList, error)
- // GetPods returns list of pods
+ // GetPods returns list of pods.
GetPods(ctx context.Context, namespace string, labelSelector *metav1.LabelSelector) (*corev1.PodList, error)
- // GetNodes returns list of nodes
+ // GetNodes returns list of nodes.
GetNodes(ctx context.Context) (*corev1.NodeList, error)
- // GetLogs returns logs for pod
+ // GetLogs returns logs for pod.
GetLogs(ctx context.Context, pod, container string) (string, error)
GetEvents(ctx context.Context, name string) (string, error)
// ApplyFile accepts manifest file contents, parses into []runtime.Object
- // and applies them against the cluster
+ // and applies them against the cluster.
ApplyFile(fileBytes []byte) error
// DoCSVWait waits until for a CSV to be applied.
DoCSVWait(ctx context.Context, key types.NamespacedName) error
diff --git a/managed/services/dbaas/kubernetes/client/load_config.go b/managed/services/dbaas/kubernetes/client/load_config.go
index 4d993af1ba..ec8cffa41c 100644
--- a/managed/services/dbaas/kubernetes/client/load_config.go
+++ b/managed/services/dbaas/kubernetes/client/load_config.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/dbaas/kubernetes/client/mock_kube_client_connector.go b/managed/services/dbaas/kubernetes/client/mock_kube_client_connector.go
index cc28b426e8..1a84ff20de 100644
--- a/managed/services/dbaas/kubernetes/client/mock_kube_client_connector.go
+++ b/managed/services/dbaas/kubernetes/client/mock_kube_client_connector.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package client
diff --git a/managed/services/dbaas/kubernetes/client/writer.go b/managed/services/dbaas/kubernetes/client/writer.go
index a058cc0531..2c5839504c 100644
--- a/managed/services/dbaas/kubernetes/client/writer.go
+++ b/managed/services/dbaas/kubernetes/client/writer.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/dbaas/kubernetes/kubernetes.go b/managed/services/dbaas/kubernetes/kubernetes.go
index 5fe45368a7..207bff645a 100644
--- a/managed/services/dbaas/kubernetes/kubernetes.go
+++ b/managed/services/dbaas/kubernetes/kubernetes.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -185,7 +185,7 @@ func NewEmpty() *Kubernetes {
}
}
-// SetKubeconfig changes kubeconfig for active client
+// SetKubeconfig changes kubeconfig for active client.
func (k *Kubernetes) SetKubeconfig(kubeconfig string) error {
k.lock.Lock()
defer k.lock.Unlock()
@@ -231,7 +231,7 @@ func (k *Kubernetes) GetDatabaseCluster(ctx context.Context, name string) (*dbaa
return k.client.GetDatabaseCluster(ctx, name)
}
-// RestartDatabaseCluster restarts database cluster
+// RestartDatabaseCluster restarts database cluster.
func (k *Kubernetes) RestartDatabaseCluster(ctx context.Context, name string) error {
k.lock.Lock()
defer k.lock.Unlock()
@@ -255,7 +255,7 @@ func (k *Kubernetes) PatchDatabaseCluster(cluster *dbaasv1.DatabaseCluster) erro
return k.client.ApplyObject(cluster)
}
-// CreateDatabaseCluster creates database cluster
+// CreateDatabaseCluster creates database cluster.
func (k *Kubernetes) CreateDatabaseCluster(cluster *dbaasv1.DatabaseCluster) error {
k.lock.Lock()
defer k.lock.Unlock()
@@ -266,7 +266,7 @@ func (k *Kubernetes) CreateDatabaseCluster(cluster *dbaasv1.DatabaseCluster) err
return k.client.ApplyObject(cluster)
}
-// DeleteDatabaseCluster deletes database cluster
+// DeleteDatabaseCluster deletes database cluster.
func (k *Kubernetes) DeleteDatabaseCluster(ctx context.Context, name string) error {
k.lock.Lock()
defer k.lock.Unlock()
@@ -279,7 +279,7 @@ func (k *Kubernetes) DeleteDatabaseCluster(ctx context.Context, name string) err
return k.client.DeleteObject(cluster)
}
-// GetDefaultStorageClassName returns first storageClassName from kubernetes cluster
+// GetDefaultStorageClassName returns first storageClassName from kubernetes cluster.
func (k *Kubernetes) GetDefaultStorageClassName(ctx context.Context) (string, error) {
k.lock.RLock()
defer k.lock.RUnlock()
@@ -293,7 +293,7 @@ func (k *Kubernetes) GetDefaultStorageClassName(ctx context.Context) (string, er
return "", errors.New("no storage classes available")
}
-// GetClusterType tries to guess the underlying kubernetes cluster based on storage class
+// GetClusterType tries to guess the underlying kubernetes cluster based on storage class.
func (k *Kubernetes) GetClusterType(ctx context.Context) (ClusterType, error) {
k.lock.RLock()
defer k.lock.RUnlock()
@@ -314,7 +314,7 @@ func (k *Kubernetes) GetClusterType(ctx context.Context) (ClusterType, error) {
return ClusterTypeGeneric, nil
}
-// getOperatorVersion parses operator version from operator deployment
+// getOperatorVersion parses operator version from operator deployment.
func (k *Kubernetes) getOperatorVersion(ctx context.Context, deploymentName, containerName string) (string, error) {
deployment, err := k.client.GetDeployment(ctx, deploymentName)
if err != nil {
@@ -328,7 +328,7 @@ func (k *Kubernetes) getOperatorVersion(ctx context.Context, deploymentName, con
return "", errors.New("unknown version of operator")
}
-// GetPSMDBOperatorVersion parses PSMDB operator version from operator deployment
+// GetPSMDBOperatorVersion parses PSMDB operator version from operator deployment.
func (k *Kubernetes) GetPSMDBOperatorVersion(ctx context.Context) (string, error) {
k.lock.RLock()
defer k.lock.RUnlock()
@@ -342,21 +342,21 @@ func (k *Kubernetes) GetPXCOperatorVersion(ctx context.Context) (string, error)
return k.getOperatorVersion(ctx, pxcDeploymentName, pxcOperatorContainerName)
}
-// GetDBaaSOperatorVersion parses DBaaS operator version from operator deployment
+// GetDBaaSOperatorVersion parses DBaaS operator version from operator deployment.
func (k *Kubernetes) GetDBaaSOperatorVersion(ctx context.Context) (string, error) {
k.lock.RLock()
defer k.lock.RUnlock()
return k.getOperatorVersion(ctx, dbaasDeploymentName, dbaasOperatorContainerName)
}
-// GetSecret returns secret by name
+// GetSecret returns secret by name.
func (k *Kubernetes) GetSecret(ctx context.Context, name string) (*corev1.Secret, error) {
k.lock.RLock()
defer k.lock.RUnlock()
return k.client.GetSecret(ctx, name)
}
-// ListSecrets returns secret by name
+// ListSecrets returns secret by name.
func (k *Kubernetes) ListSecrets(ctx context.Context) (*corev1.SecretList, error) {
k.lock.RLock()
defer k.lock.RUnlock()
@@ -912,7 +912,7 @@ func (k *Kubernetes) UpgradeOperator(ctx context.Context, namespace, name string
return err
}
-// GetServerVersion returns server version
+// GetServerVersion returns server version.
func (k *Kubernetes) GetServerVersion() (*version.Info, error) {
return k.client.GetServerVersion()
}
diff --git a/managed/services/dbaas/kubernetes/olm_operator_test.go b/managed/services/dbaas/kubernetes/olm_operator_test.go
index b9cb55d414..83906ee61b 100644
--- a/managed/services/dbaas/kubernetes/olm_operator_test.go
+++ b/managed/services/dbaas/kubernetes/olm_operator_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2020 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/dbaas/kubernetes/types.go b/managed/services/dbaas/kubernetes/types.go
index 867491f48f..db29220e1c 100644
--- a/managed/services/dbaas/kubernetes/types.go
+++ b/managed/services/dbaas/kubernetes/types.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/dbaas/kubernetes/types_test.go b/managed/services/dbaas/kubernetes/types_test.go
index 21f132a3f3..08daf4c349 100644
--- a/managed/services/dbaas/kubernetes/types_test.go
+++ b/managed/services/dbaas/kubernetes/types_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/dbaas/utils/convertors/convertors.go b/managed/services/dbaas/utils/convertors/convertors.go
index b6481ae467..a7f3d2f55d 100644
--- a/managed/services/dbaas/utils/convertors/convertors.go
+++ b/managed/services/dbaas/utils/convertors/convertors.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/dbaas/utils/convertors/convertors_test.go b/managed/services/dbaas/utils/convertors/convertors_test.go
index fd9ab7b1c6..d3eefec788 100644
--- a/managed/services/dbaas/utils/convertors/convertors_test.go
+++ b/managed/services/dbaas/utils/convertors/convertors_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/errors.go b/managed/services/errors.go
index 7b09154abb..5e752cd96c 100644
--- a/managed/services/errors.go
+++ b/managed/services/errors.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -17,8 +17,13 @@ package services
import "github.com/pkg/errors"
-// ErrAdvisorsDisabled means that advisors checks are disabled and can't be executed.
-var ErrAdvisorsDisabled = errors.New("Advisor checks are disabled")
+var (
+ // ErrAdvisorsDisabled means that advisors checks are disabled and can't be executed.
+ ErrAdvisorsDisabled = errors.New("Advisor checks are disabled")
-// ErrAlertingDisabled means Percona Alerting is disabled and its APIs can't be executed.
-var ErrAlertingDisabled = errors.New("Alerting is disabled")
+ // ErrLocationFolderPairAlreadyUsed returned when location-folder pair already in use and cannot be used for backup.
+ ErrLocationFolderPairAlreadyUsed = errors.New("location-folder pair already used")
+
+ // ErrAlertingDisabled means Percona Alerting is disabled and its APIs can't be executed.
+ ErrAlertingDisabled = errors.New("Alerting is disabled")
+)
diff --git a/managed/services/grafana/auth_server.go b/managed/services/grafana/auth_server.go
index 5f39ba3d8c..2d7cf38cc3 100644
--- a/managed/services/grafana/auth_server.go
+++ b/managed/services/grafana/auth_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -358,9 +358,14 @@ func (s *AuthServer) getFiltersForVMProxy(userID int) ([]string, error) {
filters := make([]string, 0, len(roles))
for _, r := range roles {
- if r.Filter != "" {
- filters = append(filters, r.Filter)
+ if r.Filter == "" {
+ // Special case when a user has assigned a role with no filters.
+ // In this case it's irrelevant what other roles are assigned to the user.
+ // The user shall have full access.
+ return []string{}, nil
}
+
+ filters = append(filters, r.Filter)
}
return filters, nil
}
diff --git a/managed/services/grafana/auth_server_fuzz.go b/managed/services/grafana/auth_server_fuzz.go
index 2abdb9c911..d72f17a776 100644
--- a/managed/services/grafana/auth_server_fuzz.go
+++ b/managed/services/grafana/auth_server_fuzz.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/grafana/auth_server_test.go b/managed/services/grafana/auth_server_test.go
index 7c4d44865a..77d341a36b 100644
--- a/managed/services/grafana/auth_server_test.go
+++ b/managed/services/grafana/auth_server_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -35,9 +35,9 @@ import (
"gopkg.in/reform.v1/dialects/postgresql"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
func TestNextPrefix(t *testing.T) {
@@ -294,18 +294,27 @@ func TestAuthServerAddVMGatewayToken(t *testing.T) {
c := NewClient("127.0.0.1:3000")
s := NewAuthServer(c, &checker, db)
- var roleA models.Role
- roleA.Title = "Role A"
- roleA.Filter = "filter A"
+ roleA := models.Role{
+ Title: "Role A",
+ Filter: "filter A",
+ }
err := models.CreateRole(db.Querier, &roleA)
require.NoError(t, err)
- var roleB models.Role
- roleB.Title = "Role B"
- roleB.Filter = "filter B"
+ roleB := models.Role{
+ Title: "Role B",
+ Filter: "filter B",
+ }
err = models.CreateRole(db.Querier, &roleB)
require.NoError(t, err)
+ roleC := models.Role{
+ Title: "Role C",
+ Filter: "",
+ }
+ err = models.CreateRole(db.Querier, &roleC)
+ require.NoError(t, err)
+
// Enable access control
_, err = models.UpdateSettings(db.Querier, &models.ChangeSettingsParams{
EnableAccessControl: true,
@@ -315,6 +324,7 @@ func TestAuthServerAddVMGatewayToken(t *testing.T) {
for userID, roleIDs := range map[int][]int{
1337: {int(roleA.ID)},
1338: {int(roleA.ID), int(roleB.ID)},
+ 1339: {int(roleA.ID), int(roleC.ID)},
1: {int(roleA.ID)},
} {
err := db.InTransaction(func(tx *reform.TX) error {
@@ -382,6 +392,19 @@ func TestAuthServerAddVMGatewayToken(t *testing.T) {
require.Equal(t, parsed[0], "filter A")
require.Equal(t, parsed[1], "filter B")
})
+
+ //nolint:paralleltest
+ t.Run("shall not add any filters if at least one role has full access", func(t *testing.T) {
+ rw := httptest.NewRecorder()
+ req, err := http.NewRequestWithContext(ctx, http.MethodGet, "/prometheus/api/v1/", nil)
+ require.NoError(t, err)
+
+ err = s.maybeAddVMProxyFilters(ctx, rw, req, 1339, logrus.WithField("test", t.Name()))
+ require.NoError(t, err)
+
+ headerString := rw.Header().Get(vmProxyHeaderName)
+ require.Equal(t, len(headerString), 0)
+ })
}
func Test_cleanPath(t *testing.T) {
diff --git a/managed/services/grafana/client.go b/managed/services/grafana/client.go
index c3fe0769da..684fe94864 100644
--- a/managed/services/grafana/client.go
+++ b/managed/services/grafana/client.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/grafana/client_test.go b/managed/services/grafana/client_test.go
index 546dbcaa7f..75b4e5376f 100644
--- a/managed/services/grafana/client_test.go
+++ b/managed/services/grafana/client_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/grafana/deps.go b/managed/services/grafana/deps.go
index e58ce85e8b..496065a021 100644
--- a/managed/services/grafana/deps.go
+++ b/managed/services/grafana/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/grafana/mock_aws_instance_checker_test.go b/managed/services/grafana/mock_aws_instance_checker_test.go
index c9e02a0897..66a2aee644 100644
--- a/managed/services/grafana/mock_aws_instance_checker_test.go
+++ b/managed/services/grafana/mock_aws_instance_checker_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package grafana
diff --git a/managed/services/inventory/agents.go b/managed/services/inventory/agents.go
index deae73a93b..6a27106db9 100644
--- a/managed/services/inventory/agents.go
+++ b/managed/services/inventory/agents.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -27,7 +27,7 @@ import (
"github.com/percona/pmm/api/inventorypb"
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
)
// AgentsService works with inventory API Agents.
diff --git a/managed/services/inventory/agents_test.go b/managed/services/inventory/agents_test.go
index 3e9082bd87..6157ea2d9a 100644
--- a/managed/services/inventory/agents_test.go
+++ b/managed/services/inventory/agents_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/inventory/deps.go b/managed/services/inventory/deps.go
index a1471ea79c..37c2faab3e 100644
--- a/managed/services/inventory/deps.go
+++ b/managed/services/inventory/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/inventory/grpc/agents_server.go b/managed/services/inventory/grpc/agents_server.go
index b7d1a73eb5..3e4277d394 100644
--- a/managed/services/inventory/grpc/agents_server.go
+++ b/managed/services/inventory/grpc/agents_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/inventory/grpc/nodes_server.go b/managed/services/inventory/grpc/nodes_server.go
index ba08800ad8..18b57b1d4d 100644
--- a/managed/services/inventory/grpc/nodes_server.go
+++ b/managed/services/inventory/grpc/nodes_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -106,6 +106,10 @@ func (s *nodesServer) GetNode(ctx context.Context, req *inventorypb.GetNodeReque
return res, nil
}
+func (s *nodesServer) AddNode(ctx context.Context, req *inventorypb.AddNodeRequest) (*inventorypb.AddNodeResponse, error) {
+ return s.svc.AddNode(ctx, req)
+}
+
// AddGenericNode adds Generic Node.
func (s *nodesServer) AddGenericNode(ctx context.Context, req *inventorypb.AddGenericNodeRequest) (*inventorypb.AddGenericNodeResponse, error) {
node, err := s.svc.AddGenericNode(ctx, req)
diff --git a/managed/services/inventory/grpc/services_server.go b/managed/services/inventory/grpc/services_server.go
index 72d0798124..0a6207ce87 100644
--- a/managed/services/inventory/grpc/services_server.go
+++ b/managed/services/inventory/grpc/services_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -20,21 +20,29 @@ import (
"fmt"
"github.com/AlekSi/pointer"
+ "github.com/pkg/errors"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
"github.com/percona/pmm/api/inventorypb"
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services/inventory"
+ "github.com/percona/pmm/managed/services/management/common"
)
type servicesServer struct {
- s *inventory.ServicesService
+ s *inventory.ServicesService
+ mgmtServices common.MgmtServices
inventorypb.UnimplementedServicesServer
}
// NewServicesServer returns Inventory API handler for managing Services.
-func NewServicesServer(s *inventory.ServicesService) inventorypb.ServicesServer { //nolint:ireturn
- return &servicesServer{s: s}
+func NewServicesServer(s *inventory.ServicesService, mgmtServices common.MgmtServices) inventorypb.ServicesServer { //nolint:ireturn
+ return &servicesServer{
+ s: s,
+ mgmtServices: mgmtServices,
+ }
}
var serviceTypes = map[inventorypb.ServiceType]models.ServiceType{
@@ -278,3 +286,29 @@ func (s *servicesServer) AddCustomLabels(ctx context.Context, req *inventorypb.A
func (s *servicesServer) RemoveCustomLabels(ctx context.Context, req *inventorypb.RemoveCustomLabelsRequest) (*inventorypb.RemoveCustomLabelsResponse, error) {
return s.s.RemoveCustomLabels(ctx, req)
}
+
+// ChangeService changes service configuration.
+func (s *servicesServer) ChangeService(ctx context.Context, req *inventorypb.ChangeServiceRequest) (*inventorypb.ChangeServiceResponse, error) {
+ err := s.s.ChangeService(ctx, s.mgmtServices, &models.ChangeStandardLabelsParams{
+ ServiceID: req.ServiceId,
+ Cluster: req.Cluster,
+ Environment: req.Environment,
+ ReplicationSet: req.ReplicationSet,
+ ExternalGroup: req.ExternalGroup,
+ })
+ if err != nil {
+ return nil, toAPIError(err)
+ }
+
+ return &inventorypb.ChangeServiceResponse{}, nil
+}
+
+// toAPIError converts GO errors into API-level errors.
+func toAPIError(err error) error {
+ switch {
+ case errors.Is(err, common.ErrClusterLocked):
+ return status.Error(codes.FailedPrecondition, err.Error())
+ default:
+ return err
+ }
+}
diff --git a/managed/services/inventory/inventory_metrics.go b/managed/services/inventory/inventory_metrics.go
index 7b45b92ca4..d390b95b73 100644
--- a/managed/services/inventory/inventory_metrics.go
+++ b/managed/services/inventory/inventory_metrics.go
@@ -26,7 +26,7 @@ import (
"github.com/percona/pmm/api/inventorypb"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
)
const (
@@ -68,7 +68,7 @@ func NewInventoryMetricsCollector(metrics inventoryMetrics) *InventoryMetricsCol
mAgentsDesc: prom.NewDesc(
prom.BuildFQName(prometheusNamespace, prometheusSubsystem, "agents"),
"Inventory Agent",
- []string{"agent_id", "agent_type", "service_id", "node_id", "pmm_agent_id", "disabled", "version"},
+ []string{"agent_id", "agent_type", "service_id", "node_id", "node_name", "pmm_agent_id", "disabled", "version"},
nil),
mNodesDesc: prom.NewDesc(
prom.BuildFQName(prometheusNamespace, prometheusSubsystem, "nodes"),
@@ -85,7 +85,7 @@ func NewInventoryMetricsCollector(metrics inventoryMetrics) *InventoryMetricsCol
}
}
-func GetRunsOnNodeIDByPMMAgentID(agents []*models.Agent, pmmAgentID string) string {
+func getRunsOnNodeIDByPMMAgentID(agents []*models.Agent, pmmAgentID string) string {
for _, agent := range agents {
if agent.AgentID == pmmAgentID {
return pointer.GetString(agent.RunsOnNodeID)
@@ -103,6 +103,16 @@ func (i *InventoryMetrics) GetAgentMetrics(ctx context.Context) ([]Metric, error
return err
}
+ dbNodes, err := models.FindNodes(tx.Querier, models.NodeFilters{})
+ if err != nil {
+ return err
+ }
+
+ nodeMap := make(map[string]string, len(dbNodes))
+ for _, node := range dbNodes {
+ nodeMap[node.NodeID] = node.NodeName
+ }
+
for _, agent := range dbAgents {
runsOnNodeID := ""
disabled := "0"
@@ -121,14 +131,16 @@ func (i *InventoryMetrics) GetAgentMetrics(ctx context.Context) ([]Metric, error
runsOnNodeID = pointer.GetString(agent.RunsOnNodeID)
} else {
metricValue = float64(inventorypb.AgentStatus_value[agent.Status])
- runsOnNodeID = GetRunsOnNodeIDByPMMAgentID(dbAgents, pmmAgentID)
+ runsOnNodeID = getRunsOnNodeIDByPMMAgentID(dbAgents, pmmAgentID)
}
+ nodeName := nodeMap[runsOnNodeID]
agentMetricLabels := []string{
agent.AgentID,
string(agent.AgentType),
pointer.GetString(agent.ServiceID),
runsOnNodeID,
+ nodeName,
pmmAgentID,
disabled,
pointer.GetString(agent.Version),
diff --git a/managed/services/inventory/inventory_metrics_test.go b/managed/services/inventory/inventory_metrics_test.go
index c65631588f..939ccc7b07 100644
--- a/managed/services/inventory/inventory_metrics_test.go
+++ b/managed/services/inventory/inventory_metrics_test.go
@@ -38,7 +38,7 @@ func TestNewInventoryMetricsCollector(t *testing.T) {
agentMetrics := []Metric{
{
- labels: []string{"A1", string(models.PMMAgentType), "S1", "N1", "PA1", strconv.Itoa(1), "V1"},
+ labels: []string{"A1", string(models.PMMAgentType), "S1", "N1", "NN1", "PA1", strconv.Itoa(1), "V1"},
value: float64(1),
},
}
@@ -87,13 +87,13 @@ func TestNewInventoryMetricsCollector(t *testing.T) {
const expectedAgentMetrics = `
# HELP pmm_managed_inventory_agents Inventory Agent
# TYPE pmm_managed_inventory_agents gauge
- pmm_managed_inventory_agents{agent_id="A1",agent_type="pmm-agent",disabled="1",node_id="N1",pmm_agent_id="PA1",service_id="S1",version="V1"} 1
+ pmm_managed_inventory_agents{agent_id="A1",agent_type="pmm-agent",disabled="1",node_id="N1",node_name="NN1",pmm_agent_id="PA1",service_id="S1",version="V1"} 1
`
const expectedNodeMetrics = `
# HELP pmm_managed_inventory_nodes Inventory Node
- # TYPE pmm_managed_inventory_nodes gauge
- pmm_managed_inventory_nodes{container_name="C1",node_id="N1",node_name="N1",node_type="generic"} 1
+ # TYPE pmm_managed_inventory_nodes gauge
+ pmm_managed_inventory_nodes{container_name="C1",node_id="N1",node_name="N1",node_type="generic"} 1
`
const expectedServiceMetrics = `
diff --git a/managed/services/inventory/mock_agent_service_test.go b/managed/services/inventory/mock_agent_service_test.go
index e5cb5c31a8..a0d1f1aa95 100644
--- a/managed/services/inventory/mock_agent_service_test.go
+++ b/managed/services/inventory/mock_agent_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package inventory
diff --git a/managed/services/inventory/mock_agents_registry_test.go b/managed/services/inventory/mock_agents_registry_test.go
index 17d3609ad1..b683d1ba0b 100644
--- a/managed/services/inventory/mock_agents_registry_test.go
+++ b/managed/services/inventory/mock_agents_registry_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package inventory
diff --git a/managed/services/inventory/mock_agents_state_updater_test.go b/managed/services/inventory/mock_agents_state_updater_test.go
index a073d3ee25..7953573a32 100644
--- a/managed/services/inventory/mock_agents_state_updater_test.go
+++ b/managed/services/inventory/mock_agents_state_updater_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package inventory
diff --git a/managed/services/inventory/mock_connection_checker_test.go b/managed/services/inventory/mock_connection_checker_test.go
index fca0ffe2da..8f73889c24 100644
--- a/managed/services/inventory/mock_connection_checker_test.go
+++ b/managed/services/inventory/mock_connection_checker_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package inventory
diff --git a/managed/services/inventory/mock_inventory_metrics_test.go b/managed/services/inventory/mock_inventory_metrics_test.go
index 55e461e1cb..aa22cfcc6e 100644
--- a/managed/services/inventory/mock_inventory_metrics_test.go
+++ b/managed/services/inventory/mock_inventory_metrics_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package inventory
diff --git a/managed/services/inventory/mock_prometheus_service_test.go b/managed/services/inventory/mock_prometheus_service_test.go
index 03d2770440..1b82cbe503 100644
--- a/managed/services/inventory/mock_prometheus_service_test.go
+++ b/managed/services/inventory/mock_prometheus_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package inventory
diff --git a/managed/services/inventory/mock_version_cache_test.go b/managed/services/inventory/mock_version_cache_test.go
index 141a110d5f..4e0286a075 100644
--- a/managed/services/inventory/mock_version_cache_test.go
+++ b/managed/services/inventory/mock_version_cache_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package inventory
diff --git a/managed/services/inventory/nodes.go b/managed/services/inventory/nodes.go
index 10516dfd2d..31a4f304d4 100644
--- a/managed/services/inventory/nodes.go
+++ b/managed/services/inventory/nodes.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -46,11 +46,9 @@ func NewNodesService(db *reform.DB, r agentsRegistry, state agentsStateUpdater,
}
// List returns a list of all Nodes.
-//
-//nolint:unparam
func (s *NodesService) List(ctx context.Context, filters models.NodeFilters) ([]inventorypb.Node, error) {
var nodes []*models.Node
- e := s.db.InTransaction(func(tx *reform.TX) error {
+ e := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
var err error
nodes, err = models.FindNodes(tx.Querier, filters)
return err
@@ -70,9 +68,9 @@ func (s *NodesService) List(ctx context.Context, filters models.NodeFilters) ([]
}
// Get returns a single Node by ID.
-func (s *NodesService) Get(ctx context.Context, req *inventorypb.GetNodeRequest) (inventorypb.Node, error) { //nolint:unparam,ireturn
+func (s *NodesService) Get(ctx context.Context, req *inventorypb.GetNodeRequest) (inventorypb.Node, error) { //nolint:ireturn
modelNode := &models.Node{}
- e := s.db.InTransaction(func(tx *reform.TX) error {
+ e := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
var err error
modelNode, err = models.FindNodeByID(tx.Querier, req.NodeId)
if err != nil {
@@ -92,9 +90,49 @@ func (s *NodesService) Get(ctx context.Context, req *inventorypb.GetNodeRequest)
return node, nil
}
+// AddNode adds any type of Node.
+func (s *NodesService) AddNode(ctx context.Context, req *inventorypb.AddNodeRequest) (*inventorypb.AddNodeResponse, error) {
+ res := &inventorypb.AddNodeResponse{}
+
+ switch req.Request.(type) {
+ case *inventorypb.AddNodeRequest_Generic:
+ node, err := s.AddGenericNode(ctx, req.GetGeneric())
+ if err != nil {
+ return nil, err
+ }
+ res.Node = &inventorypb.AddNodeResponse_Generic{Generic: node}
+ case *inventorypb.AddNodeRequest_Container:
+ node, err := s.AddContainerNode(ctx, req.GetContainer())
+ if err != nil {
+ return nil, err
+ }
+ res.Node = &inventorypb.AddNodeResponse_Container{Container: node}
+ case *inventorypb.AddNodeRequest_Remote:
+ node, err := s.AddRemoteNode(ctx, req.GetRemote())
+ if err != nil {
+ return nil, err
+ }
+ res.Node = &inventorypb.AddNodeResponse_Remote{Remote: node}
+ case *inventorypb.AddNodeRequest_RemoteRds:
+ node, err := s.AddRemoteRDSNode(ctx, req.GetRemoteRds())
+ if err != nil {
+ return nil, err
+ }
+ res.Node = &inventorypb.AddNodeResponse_RemoteRds{RemoteRds: node}
+ case *inventorypb.AddNodeRequest_RemoteAzure:
+ node, err := s.AddRemoteAzureDatabaseNode(ctx, req.GetRemoteAzure())
+ if err != nil {
+ return nil, err
+ }
+ res.Node = &inventorypb.AddNodeResponse_RemoteAzureDatabase{RemoteAzureDatabase: node}
+ default:
+ return nil, errors.Errorf("invalid request %v", req.GetRequest())
+ }
+
+ return res, nil
+}
+
// AddGenericNode adds Generic Node.
-//
-//nolint:unparam
func (s *NodesService) AddGenericNode(ctx context.Context, req *inventorypb.AddGenericNodeRequest) (*inventorypb.GenericNode, error) {
params := &models.CreateNodeParams{
NodeName: req.NodeName,
@@ -108,7 +146,7 @@ func (s *NodesService) AddGenericNode(ctx context.Context, req *inventorypb.AddG
}
node := &models.Node{}
- e := s.db.InTransaction(func(tx *reform.TX) error {
+ e := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
var err error
node, err = models.CreateNode(tx.Querier, models.GenericNodeType, params)
if err != nil {
@@ -129,8 +167,6 @@ func (s *NodesService) AddGenericNode(ctx context.Context, req *inventorypb.AddG
}
// AddContainerNode adds Container Node.
-//
-//nolint:unparam
func (s *NodesService) AddContainerNode(ctx context.Context, req *inventorypb.AddContainerNodeRequest) (*inventorypb.ContainerNode, error) {
params := &models.CreateNodeParams{
NodeName: req.NodeName,
@@ -145,7 +181,7 @@ func (s *NodesService) AddContainerNode(ctx context.Context, req *inventorypb.Ad
}
node := &models.Node{}
- e := s.db.InTransaction(func(tx *reform.TX) error {
+ e := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
var err error
node, err = models.CreateNode(tx.Querier, models.ContainerNodeType, params)
if err != nil {
@@ -166,8 +202,6 @@ func (s *NodesService) AddContainerNode(ctx context.Context, req *inventorypb.Ad
}
// AddRemoteNode adds Remote Node.
-//
-//nolint:unparam
func (s *NodesService) AddRemoteNode(ctx context.Context, req *inventorypb.AddRemoteNodeRequest) (*inventorypb.RemoteNode, error) {
params := &models.CreateNodeParams{
NodeName: req.NodeName,
@@ -179,7 +213,7 @@ func (s *NodesService) AddRemoteNode(ctx context.Context, req *inventorypb.AddRe
}
node := &models.Node{}
- e := s.db.InTransaction(func(tx *reform.TX) error {
+ e := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
var err error
node, err = models.CreateNode(tx.Querier, models.RemoteNodeType, params)
if err != nil {
@@ -200,8 +234,6 @@ func (s *NodesService) AddRemoteNode(ctx context.Context, req *inventorypb.AddRe
}
// AddRemoteRDSNode adds a new RDS node
-//
-//nolint:unparam
func (s *NodesService) AddRemoteRDSNode(ctx context.Context, req *inventorypb.AddRemoteRDSNodeRequest) (*inventorypb.RemoteRDSNode, error) {
params := &models.CreateNodeParams{
NodeName: req.NodeName,
@@ -213,7 +245,7 @@ func (s *NodesService) AddRemoteRDSNode(ctx context.Context, req *inventorypb.Ad
}
node := &models.Node{}
- e := s.db.InTransaction(func(tx *reform.TX) error {
+ e := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
var err error
node, err = models.CreateNode(tx.Querier, models.RemoteRDSNodeType, params)
if err != nil {
@@ -235,7 +267,7 @@ func (s *NodesService) AddRemoteRDSNode(ctx context.Context, req *inventorypb.Ad
// AddRemoteAzureDatabaseNode adds a new Azure database node
//
-//nolint:unparam,dupl
+//nolint:dupl
func (s *NodesService) AddRemoteAzureDatabaseNode(ctx context.Context, req *inventorypb.AddRemoteAzureDatabaseNodeRequest) (*inventorypb.RemoteAzureDatabaseNode, error) {
params := &models.CreateNodeParams{
NodeName: req.NodeName,
@@ -247,7 +279,7 @@ func (s *NodesService) AddRemoteAzureDatabaseNode(ctx context.Context, req *inve
}
node := &models.Node{}
- e := s.db.InTransaction(func(tx *reform.TX) error {
+ e := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
var err error
node, err = models.CreateNode(tx.Querier, models.RemoteAzureDatabaseNodeType, params)
if err != nil {
@@ -274,7 +306,7 @@ func (s *NodesService) Remove(ctx context.Context, id string, force bool) error
idsToKick := make(map[string]struct{})
idsToSetState := make(map[string]struct{})
- if e := s.db.InTransaction(func(tx *reform.TX) error {
+ if e := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
mode := models.RemoveRestrict
if force {
mode = models.RemoveCascade
diff --git a/managed/services/inventory/nodes_test.go b/managed/services/inventory/nodes_test.go
index afd2ad42a8..d03ab7ed8c 100644
--- a/managed/services/inventory/nodes_test.go
+++ b/managed/services/inventory/nodes_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -16,6 +16,7 @@
package inventory
import (
+ "fmt"
"testing"
"github.com/stretchr/testify/assert"
@@ -31,7 +32,7 @@ import (
func TestNodes(t *testing.T) {
t.Run("Basic", func(t *testing.T) {
_, _, ns, teardown, ctx, _ := setup(t)
- defer teardown(t)
+ t.Cleanup(func() { teardown(t) })
actualNodes, err := ns.List(ctx, models.NodeFilters{})
require.NoError(t, err)
@@ -63,7 +64,7 @@ func TestNodes(t *testing.T) {
t.Run("GetEmptyID", func(t *testing.T) {
_, _, ns, teardown, ctx, _ := setup(t)
- defer teardown(t)
+ t.Cleanup(func() { teardown(t) })
getNodeResponse, err := ns.Get(ctx, &inventorypb.GetNodeRequest{NodeId: ""})
tests.AssertGRPCError(t, status.New(codes.InvalidArgument, `Empty Node ID.`), err)
@@ -72,7 +73,7 @@ func TestNodes(t *testing.T) {
t.Run("AddNameEmpty", func(t *testing.T) {
_, _, ns, teardown, ctx, _ := setup(t)
- defer teardown(t)
+ t.Cleanup(func() { teardown(t) })
_, err := ns.AddGenericNode(ctx, &inventorypb.AddGenericNodeRequest{NodeName: ""})
tests.AssertGRPCError(t, status.New(codes.InvalidArgument, `Empty Node name.`), err)
@@ -80,7 +81,7 @@ func TestNodes(t *testing.T) {
t.Run("AddNameNotUnique", func(t *testing.T) {
_, _, ns, teardown, ctx, _ := setup(t)
- defer teardown(t)
+ t.Cleanup(func() { teardown(t) })
_, err := ns.AddGenericNode(ctx, &inventorypb.AddGenericNodeRequest{NodeName: "test", Address: "test"})
require.NoError(t, err)
@@ -91,7 +92,7 @@ func TestNodes(t *testing.T) {
t.Run("AddHostnameNotUnique", func(t *testing.T) {
_, _, ns, teardown, ctx, _ := setup(t)
- defer teardown(t)
+ t.Cleanup(func() { teardown(t) })
_, err := ns.AddGenericNode(ctx, &inventorypb.AddGenericNodeRequest{NodeName: "test1", Address: "test"})
require.NoError(t, err)
@@ -100,24 +101,9 @@ func TestNodes(t *testing.T) {
require.NoError(t, err)
})
- /*
- TODO
- t.Run("AddInstanceRegionNotUnique", func(t *testing.T) {
- ns, teardown := setup(t)
- defer teardown(t)
-
- _, err := ns.AddRemoteAmazonRDSNode(ctx, &inventorypb.AddRemoteAmazonRDSNodeRequest{NodeName: "test1", Instance: "test-instance", Region: "test-region"})
- require.NoError(t, err)
-
- _, err = ns.AddRemoteAmazonRDSNode(ctx, &inventorypb.AddRemoteAmazonRDSNodeRequest{NodeName: "test2", Instance: "test-instance", Region: "test-region"})
- expected := status.New(codes.AlreadyExists, `Node with instance "test-instance" and region "test-region" already exists.`)
- tests.AssertGRPCError(t, expected, err)
- })
- */
-
- t.Run("AddRemoteRDSNode", func(t *testing.T) {
+ t.Run("AddRemoteRDSNodeNotUnique", func(t *testing.T) {
_, _, ns, teardown, ctx, _ := setup(t)
- defer teardown(t)
+ t.Cleanup(func() { teardown(t) })
_, err := ns.AddRemoteRDSNode(ctx, &inventorypb.AddRemoteRDSNodeRequest{NodeName: "test1", Region: "test-region", Address: "test"})
require.NoError(t, err)
@@ -135,3 +121,250 @@ func TestNodes(t *testing.T) {
tests.AssertGRPCError(t, status.New(codes.NotFound, `Node with ID "no-such-id" not found.`), err)
})
}
+
+func TestAddNode(t *testing.T) {
+ t.Run("BasicGeneric", func(t *testing.T) {
+ const nodeID = "/node_id/00000000-0000-4000-8000-000000000005"
+ _, _, ns, teardown, ctx, _ := setup(t)
+ t.Cleanup(func() { teardown(t) })
+
+ actualNodes, err := ns.List(ctx, models.NodeFilters{})
+ require.NoError(t, err)
+ require.Len(t, actualNodes, 1) // PMM Server Node
+
+ addNodeResponse, err := ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_Generic{
+ Generic: &inventorypb.AddGenericNodeRequest{NodeName: "test-bm", Region: "test-region", Address: "test"},
+ },
+ })
+ require.NoError(t, err)
+
+ expectedNode := &inventorypb.GenericNode{
+ NodeId: nodeID,
+ NodeName: "test-bm",
+ Region: "test-region",
+ Address: "test",
+ }
+ assert.Equal(t, expectedNode, addNodeResponse.GetGeneric())
+
+ getNodeResponse, err := ns.Get(ctx, &inventorypb.GetNodeRequest{NodeId: nodeID})
+ require.NoError(t, err)
+ assert.Equal(t, expectedNode, getNodeResponse)
+
+ nodesResponse, err := ns.List(ctx, models.NodeFilters{})
+ require.NoError(t, err)
+ require.Len(t, nodesResponse, 2)
+ assert.Equal(t, expectedNode, nodesResponse[0])
+
+ err = ns.Remove(ctx, nodeID, false)
+ require.NoError(t, err)
+ getNodeResponse, err = ns.Get(ctx, &inventorypb.GetNodeRequest{NodeId: nodeID})
+ tests.AssertGRPCError(t, status.New(codes.NotFound, fmt.Sprintf("Node with ID %q not found.", nodeID)), err)
+ assert.Nil(t, getNodeResponse)
+ })
+
+ t.Run("AddAllNodeTypes", func(t *testing.T) {
+ const (
+ nodeID1 = "/node_id/00000000-0000-4000-8000-000000000005"
+ nodeID2 = "/node_id/00000000-0000-4000-8000-000000000006"
+ nodeID3 = "/node_id/00000000-0000-4000-8000-000000000007"
+ nodeID4 = "/node_id/00000000-0000-4000-8000-000000000008"
+ nodeID5 = "/node_id/00000000-0000-4000-8000-000000000009"
+ )
+ _, _, ns, teardown, ctx, _ := setup(t)
+ t.Cleanup(func() { teardown(t) })
+
+ actualNodes, err := ns.List(ctx, models.NodeFilters{})
+ require.NoError(t, err)
+ require.Len(t, actualNodes, 1) // PMM Server Node
+
+ expectedNode1 := &inventorypb.GenericNode{
+ NodeId: nodeID1,
+ NodeName: "test-name1",
+ Region: "test-region",
+ Address: "test1",
+ }
+ addNodeResponse, err := ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_Generic{
+ Generic: &inventorypb.AddGenericNodeRequest{
+ NodeName: "test-name1",
+ Region: "test-region",
+ Address: "test1",
+ },
+ },
+ })
+ require.NoError(t, err)
+ assert.Equal(t, expectedNode1, addNodeResponse.GetGeneric())
+
+ expectedNode2 := &inventorypb.ContainerNode{
+ NodeId: nodeID2,
+ NodeName: "test-name2",
+ Region: "test-region",
+ Address: "test2",
+ }
+ addNodeResponse, err = ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_Container{
+ Container: &inventorypb.AddContainerNodeRequest{
+ NodeName: "test-name2",
+ Region: "test-region",
+ Address: "test2",
+ },
+ },
+ })
+ require.NoError(t, err)
+ assert.Equal(t, expectedNode2, addNodeResponse.GetContainer())
+
+ expectedNode3 := &inventorypb.RemoteNode{
+ NodeId: nodeID3,
+ NodeName: "test-name3",
+ Region: "test-region",
+ Address: "test3",
+ CustomLabels: map[string]string{
+ "testkey": "test-value",
+ "region": "test-region",
+ },
+ }
+ addNodeResponse, err = ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_Remote{
+ Remote: &inventorypb.AddRemoteNodeRequest{
+ NodeName: "test-name3",
+ Region: "test-region",
+ Address: "test3",
+ CustomLabels: map[string]string{
+ "testkey": "test-value",
+ "region": "test-region",
+ },
+ },
+ },
+ })
+ require.NoError(t, err)
+ assert.Equal(t, expectedNode3, addNodeResponse.GetRemote())
+
+ expectedNode4 := &inventorypb.RemoteAzureDatabaseNode{
+ NodeId: nodeID4,
+ NodeName: "test-name4",
+ Region: "test-region",
+ Az: "test-region-az",
+ Address: "test4",
+ }
+ addNodeResponse, err = ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_RemoteAzure{
+ RemoteAzure: &inventorypb.AddRemoteAzureDatabaseNodeRequest{
+ NodeName: "test-name4",
+ Region: "test-region",
+ Az: "test-region-az",
+ Address: "test4",
+ },
+ },
+ })
+ require.NoError(t, err)
+ assert.Equal(t, expectedNode4, addNodeResponse.GetRemoteAzureDatabase())
+
+ expectedNode5 := &inventorypb.RemoteRDSNode{
+ NodeId: nodeID5,
+ NodeName: "test-name5",
+ Region: "test-region",
+ Az: "test-region-az",
+ Address: "test5",
+ }
+ addNodeResponse, err = ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_RemoteRds{
+ RemoteRds: &inventorypb.AddRemoteRDSNodeRequest{
+ NodeName: "test-name5",
+ Region: "test-region",
+ Az: "test-region-az",
+ Address: "test5",
+ },
+ },
+ })
+ require.NoError(t, err)
+ assert.Equal(t, expectedNode5, addNodeResponse.GetRemoteRds())
+
+ getNodeResponse, err := ns.Get(ctx, &inventorypb.GetNodeRequest{NodeId: nodeID1})
+ require.NoError(t, err)
+ assert.Equal(t, expectedNode1, getNodeResponse)
+
+ nodesResponse, err := ns.List(ctx, models.NodeFilters{})
+ require.NoError(t, err)
+ require.Len(t, nodesResponse, 6)
+ assert.Equal(t, expectedNode1, nodesResponse[0])
+
+ err = ns.Remove(ctx, nodeID1, false)
+ require.NoError(t, err)
+ getNodeResponse, err = ns.Get(ctx, &inventorypb.GetNodeRequest{NodeId: nodeID1})
+ tests.AssertGRPCError(t, status.New(codes.NotFound, fmt.Sprintf("Node with ID %q not found.", nodeID1)), err)
+ assert.Nil(t, getNodeResponse)
+ })
+
+ t.Run("AddRemoteRDSNodeNonUnique", func(t *testing.T) {
+ _, _, ns, teardown, ctx, _ := setup(t)
+ t.Cleanup(func() { teardown(t) })
+
+ _, err := ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_RemoteRds{
+ RemoteRds: &inventorypb.AddRemoteRDSNodeRequest{NodeName: "test1", Region: "test-region", Address: "test"},
+ },
+ })
+ require.NoError(t, err)
+
+ _, err = ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_RemoteRds{
+ RemoteRds: &inventorypb.AddRemoteRDSNodeRequest{NodeName: "test2", Region: "test-region", Address: "test"},
+ },
+ })
+ expected := status.New(codes.AlreadyExists, `Node with instance "test" and region "test-region" already exists.`)
+ tests.AssertGRPCError(t, expected, err)
+ })
+
+ t.Run("AddHostnameNotUnique", func(t *testing.T) {
+ _, _, ns, teardown, ctx, _ := setup(t)
+ t.Cleanup(func() { teardown(t) })
+
+ _, err := ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_Generic{
+ Generic: &inventorypb.AddGenericNodeRequest{NodeName: "test1", Address: "test"},
+ },
+ })
+ require.NoError(t, err)
+
+ _, err = ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_Generic{
+ Generic: &inventorypb.AddGenericNodeRequest{NodeName: "test2", Address: "test"},
+ },
+ })
+ require.NoError(t, err)
+ })
+
+ t.Run("AddNameEmpty", func(t *testing.T) {
+ _, _, ns, teardown, ctx, _ := setup(t)
+ t.Cleanup(func() { teardown(t) })
+
+ _, err := ns.AddNode(ctx,
+ &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_Generic{
+ Generic: &inventorypb.AddGenericNodeRequest{NodeName: ""},
+ },
+ },
+ )
+ tests.AssertGRPCError(t, status.New(codes.InvalidArgument, `Empty Node name.`), err)
+ })
+
+ t.Run("AddNameNotUnique", func(t *testing.T) {
+ _, _, ns, teardown, ctx, _ := setup(t)
+ t.Cleanup(func() { teardown(t) })
+
+ _, err := ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_Generic{
+ Generic: &inventorypb.AddGenericNodeRequest{NodeName: "test", Address: "test"},
+ },
+ })
+ require.NoError(t, err)
+
+ _, err = ns.AddNode(ctx, &inventorypb.AddNodeRequest{
+ Request: &inventorypb.AddNodeRequest_Remote{
+ Remote: &inventorypb.AddRemoteNodeRequest{NodeName: "test"},
+ },
+ })
+ tests.AssertGRPCError(t, status.New(codes.AlreadyExists, `Node with name "test" already exists.`), err)
+ })
+}
diff --git a/managed/services/inventory/services.go b/managed/services/inventory/services.go
index a742b24c92..89e6d3b966 100644
--- a/managed/services/inventory/services.go
+++ b/managed/services/inventory/services.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -24,6 +24,7 @@ import (
"github.com/percona/pmm/api/inventorypb"
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services"
+ "github.com/percona/pmm/managed/services/management/common"
)
// ServicesService works with inventory API Services.
@@ -381,18 +382,10 @@ func (ss *ServicesService) AddCustomLabels(ctx context.Context, req *inventorypb
return nil, errTx
}
- // Update scrape configuration
- ss.vmdb.RequestConfigurationUpdate()
-
- agents, err := models.FindPMMAgentsForService(ss.db.Querier, req.ServiceId)
- if err != nil {
+ if err := ss.updateScrapeConfig(ctx, req.ServiceId); err != nil {
return nil, err
}
- for _, a := range agents {
- ss.state.RequestStateUpdate(ctx, a.AgentID)
- }
-
return &inventorypb.AddCustomLabelsResponse{}, nil
}
@@ -432,17 +425,50 @@ func (ss *ServicesService) RemoveCustomLabels(ctx context.Context, req *inventor
return nil, errTx
}
- // Update scrape configuration
+ if err := ss.updateScrapeConfig(ctx, req.ServiceId); err != nil {
+ return nil, err
+ }
+
+ return &inventorypb.RemoveCustomLabelsResponse{}, nil
+}
+
+// ChangeService changes service configuration.
+func (ss *ServicesService) ChangeService(ctx context.Context, mgmtServices common.MgmtServices, params *models.ChangeStandardLabelsParams) error {
+ if err := mgmtServices.RemoveScheduledTasks(ctx, ss.db, params); err != nil {
+ return err
+ }
+
+ errTx := ss.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
+ err := models.ChangeStandardLabels(tx.Querier, params.ServiceID, models.ServiceStandardLabelsParams{
+ Cluster: params.Cluster,
+ Environment: params.Environment,
+ ReplicationSet: params.ReplicationSet,
+ ExternalGroup: params.ExternalGroup,
+ })
+ return err
+ })
+ if errTx != nil {
+ return errTx
+ }
+
+ if err := ss.updateScrapeConfig(ctx, params.ServiceID); err != nil {
+ return err
+ }
+
+ return nil
+}
+
+func (ss *ServicesService) updateScrapeConfig(ctx context.Context, serviceID string) error {
ss.vmdb.RequestConfigurationUpdate()
- agents, err := models.FindPMMAgentsForService(ss.db.Querier, req.ServiceId)
+ agents, err := models.FindPMMAgentsForService(ss.db.Querier, serviceID)
if err != nil {
- return nil, err
+ return err
}
for _, a := range agents {
ss.state.RequestStateUpdate(ctx, a.AgentID)
}
- return &inventorypb.RemoveCustomLabelsResponse{}, nil
+ return nil
}
diff --git a/managed/services/inventory/services_test.go b/managed/services/inventory/services_test.go
index e556daf998..40f0d75d0b 100644
--- a/managed/services/inventory/services_test.go
+++ b/managed/services/inventory/services_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -33,9 +33,9 @@ import (
"github.com/percona/pmm/api/inventorypb"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
func setup(t *testing.T) (*ServicesService, *AgentsService, *NodesService, func(t *testing.T), context.Context, *mockPrometheusService) {
@@ -104,6 +104,7 @@ func TestServices(t *testing.T) {
expectedService := &inventorypb.MySQLService{
ServiceId: "/service_id/00000000-0000-4000-8000-000000000005",
ServiceName: "test-mysql",
+ Cluster: "test-mysql",
NodeId: models.PMMServerNodeID,
Address: "127.0.0.1",
Port: 3306,
@@ -259,6 +260,7 @@ func TestServices(t *testing.T) {
expectedService := &inventorypb.MySQLService{
ServiceId: "/service_id/00000000-0000-4000-8000-000000000005",
ServiceName: "test-mysql-socket",
+ Cluster: "test-mysql-socket",
NodeId: models.PMMServerNodeID,
Socket: "/var/run/mysqld/mysqld.sock",
}
@@ -333,6 +335,7 @@ func TestServices(t *testing.T) {
expectedMongoDBService := &inventorypb.MongoDBService{
ServiceId: "/service_id/00000000-0000-4000-8000-000000000005",
ServiceName: "test-mongo",
+ Cluster: "test-mongo",
NodeId: models.PMMServerNodeID,
Address: "127.0.0.1",
Port: 27017,
@@ -374,6 +377,7 @@ func TestServices(t *testing.T) {
expectedPostgreSQLService := &inventorypb.PostgreSQLService{
ServiceId: "/service_id/00000000-0000-4000-8000-000000000005",
ServiceName: "test-postgres",
+ Cluster: "test-postgres",
DatabaseName: "postgres",
NodeId: models.PMMServerNodeID,
Address: "127.0.0.1",
@@ -414,6 +418,7 @@ func TestServices(t *testing.T) {
expectedPostgreSQLService := &inventorypb.PostgreSQLService{
ServiceId: "/service_id/00000000-0000-4000-8000-000000000005",
ServiceName: "test-postgres",
+ Cluster: "test-postgres",
DatabaseName: "postgres",
NodeId: models.PMMServerNodeID,
Socket: "/var/run/postgresql",
@@ -492,6 +497,7 @@ func TestServices(t *testing.T) {
expectedProxySQLService := &inventorypb.ProxySQLService{
ServiceId: "/service_id/00000000-0000-4000-8000-000000000005",
ServiceName: "test-proxysql",
+ Cluster: "test-proxysql",
NodeId: models.PMMServerNodeID,
Address: "127.0.0.1",
Port: 6033,
@@ -531,6 +537,7 @@ func TestServices(t *testing.T) {
expectedService := &inventorypb.ProxySQLService{
ServiceId: "/service_id/00000000-0000-4000-8000-000000000005",
ServiceName: "test-proxysql-socket",
+ Cluster: "test-proxysql-socket",
NodeId: models.PMMServerNodeID,
Socket: "/tmp/proxysql.sock",
}
@@ -602,6 +609,7 @@ func TestServices(t *testing.T) {
expectedHAProxyService := &inventorypb.HAProxyService{
ServiceId: "/service_id/00000000-0000-4000-8000-000000000005",
ServiceName: "test-haproxy-service",
+ Cluster: "test-haproxy-service",
NodeId: models.PMMServerNodeID,
}
assert.Equal(t, expectedHAProxyService, actualHAProxyService)
@@ -639,6 +647,7 @@ func TestServices(t *testing.T) {
expectedExternalService := &inventorypb.ExternalService{
ServiceId: "/service_id/00000000-0000-4000-8000-000000000005",
ServiceName: "test-external-service",
+ Cluster: "test-external-service",
NodeId: models.PMMServerNodeID,
Group: "external",
}
@@ -730,6 +739,7 @@ func TestServices(t *testing.T) {
expectedService := &inventorypb.MongoDBService{
ServiceId: "/service_id/00000000-0000-4000-8000-000000000005",
ServiceName: "test-mongodb-socket",
+ Cluster: "test-mongodb-socket",
NodeId: models.PMMServerNodeID,
Socket: "/tmp/mongodb-27017.sock",
}
diff --git a/managed/services/management/agent.go b/managed/services/management/agent.go
index 645c31c7f9..b501440cd5 100644
--- a/managed/services/management/agent.go
+++ b/managed/services/management/agent.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/agent_test.go b/managed/services/management/agent_test.go
index b79b6f1a14..d88718ba99 100644
--- a/managed/services/management/agent_test.go
+++ b/managed/services/management/agent_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -32,9 +32,9 @@ import (
agentv1beta1 "github.com/percona/pmm/api/managementpb/agent"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
var now time.Time
diff --git a/managed/services/management/alerting/deps.go b/managed/services/management/alerting/deps.go
index 6b21b5387c..42ea52543c 100644
--- a/managed/services/management/alerting/deps.go
+++ b/managed/services/management/alerting/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/alerting/mock_grafana_client_test.go b/managed/services/management/alerting/mock_grafana_client_test.go
index 917915019c..e57dadf233 100644
--- a/managed/services/management/alerting/mock_grafana_client_test.go
+++ b/managed/services/management/alerting/mock_grafana_client_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package alerting
diff --git a/managed/services/management/alerting/service.go b/managed/services/management/alerting/service.go
index ff5453959a..cd972dd2b7 100644
--- a/managed/services/management/alerting/service.go
+++ b/managed/services/management/alerting/service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -32,7 +32,6 @@ import (
"github.com/AlekSi/pointer"
"github.com/percona-platform/saas/pkg/alert"
"github.com/percona-platform/saas/pkg/common"
- "github.com/percona/promconfig"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
"google.golang.org/grpc/codes"
@@ -59,18 +58,6 @@ const (
dirPerm = os.FileMode(0o775)
)
-// TemplateInfo represents alerting rule template information from various sources.
-//
-// TODO We already have models.Template, iav1beta1.Template, and alert.Template.
-//
-// We probably can remove that type.
-type TemplateInfo struct {
- alert.Template
- Yaml string
- Source alerting.TemplateSource
- CreatedAt *time.Time
-}
-
// Service is responsible alerting templates and rules creation from them.
type Service struct {
db *reform.DB
@@ -81,7 +68,7 @@ type Service struct {
platformPublicKeys []string
rw sync.RWMutex
- templates map[string]TemplateInfo
+ templates map[string]models.Template
alerting.UnimplementedAlertingServer
}
@@ -108,7 +95,7 @@ func NewService(db *reform.DB, platformClient *platform.Client, grafanaClient gr
grafanaClient: grafanaClient,
userTemplatesPath: templatesDir,
platformPublicKeys: platformPublicKeys,
- templates: make(map[string]TemplateInfo),
+ templates: make(map[string]models.Template),
}
return s, nil
@@ -125,11 +112,11 @@ func (s *Service) Enabled() bool {
}
// GetTemplates return collected templates.
-func (s *Service) GetTemplates() map[string]TemplateInfo {
+func (s *Service) GetTemplates() map[string]models.Template {
s.rw.RLock()
defer s.rw.RUnlock()
- res := make(map[string]TemplateInfo, len(s.templates))
+ res := make(map[string]models.Template, len(s.templates))
for n, r := range s.templates {
res[n] = r
}
@@ -142,23 +129,27 @@ func (s *Service) GetTemplates() map[string]TemplateInfo {
// User file templates: read from yaml files created by the user in `/srv/alerting/templates`.
// User API templates: in the DB created using the API.
func (s *Service) CollectTemplates(ctx context.Context) {
+ var templates []*models.Template
builtInTemplates, err := s.loadTemplatesFromAssets(ctx)
if err != nil {
s.l.Errorf("Failed to load built-in rule templates: %s.", err)
return
}
+ templates = append(templates, builtInTemplates...)
userDefinedTemplates, err := s.loadTemplatesFromUserFiles(ctx)
if err != nil {
s.l.Errorf("Failed to load user-defined rule templates: %s.", err)
return
}
+ templates = append(templates, userDefinedTemplates...)
dbTemplates, err := s.loadTemplatesFromDB()
if err != nil {
s.l.Errorf("Failed to load rule templates from DB: %s.", err)
return
}
+ templates = append(templates, dbTemplates...)
saasTemplates, err := s.downloadTemplates(ctx)
if err != nil {
@@ -166,48 +157,20 @@ func (s *Service) CollectTemplates(ctx context.Context) {
// we should still collect and show the Built-In templates.
s.l.Errorf("Failed to download rule templates from SaaS: %s.", err)
}
-
- templates := make([]TemplateInfo, 0, len(builtInTemplates)+len(userDefinedTemplates)+len(dbTemplates)+len(saasTemplates))
-
- for _, t := range builtInTemplates {
- templates = append(templates, TemplateInfo{
- Template: t,
- Source: alerting.TemplateSource_BUILT_IN,
- })
- }
-
- for _, t := range userDefinedTemplates {
- templates = append(templates, TemplateInfo{
- Template: t,
- Source: alerting.TemplateSource_USER_FILE,
- })
- }
-
- for _, t := range saasTemplates {
- templates = append(templates, TemplateInfo{
- Template: t,
- Source: alerting.TemplateSource_SAAS,
- })
- }
-
- templates = append(templates, dbTemplates...)
+ templates = append(templates, saasTemplates...)
// replace previously stored templates with newly collected ones.
s.rw.Lock()
defer s.rw.Unlock()
- s.templates = make(map[string]TemplateInfo, len(templates))
+ s.templates = make(map[string]models.Template, len(templates))
for _, t := range templates {
- // TODO Check for name clashes? Allow users to re-define built-in templates?
- // Reserve prefix for built-in or user-defined templates?
- // https://jira.percona.com/browse/PMM-7023
-
- s.templates[t.Name] = t
+ s.templates[t.Name] = *t
}
}
// loadTemplatesFromAssets loads built-in alerting rule templates from pmm-managed binary's assets.
-func (s *Service) loadTemplatesFromAssets(ctx context.Context) ([]alert.Template, error) {
- var res []alert.Template
+func (s *Service) loadTemplatesFromAssets(ctx context.Context) ([]*models.Template, error) {
+ var res []*models.Template
walkDirFunc := func(path string, d fs.DirEntry, err error) error {
if err != nil {
return errors.Wrapf(err, "error occurred while traversing templates folder: %s", path)
@@ -259,7 +222,12 @@ func (s *Service) loadTemplatesFromAssets(ctx context.Context) ([]alert.Template
return errors.Errorf("%s %q: template should contain exactly two annotations: summary and description", path, t.Name)
}
- res = append(res, t)
+ tm, err := models.ConvertTemplate(&t, models.BuiltInSource)
+ if err != nil {
+ return errors.Wrap(err, "failed to convert alert rule template")
+ }
+
+ res = append(res, tm)
return nil
}
err := fs.WalkDir(data.AlertRuleTemplates, ".", walkDirFunc)
@@ -270,13 +238,13 @@ func (s *Service) loadTemplatesFromAssets(ctx context.Context) ([]alert.Template
}
// loadTemplatesFromUserFiles loads user's alerting rule templates from /srv/alerting/templates.
-func (s *Service) loadTemplatesFromUserFiles(ctx context.Context) ([]alert.Template, error) {
+func (s *Service) loadTemplatesFromUserFiles(ctx context.Context) ([]*models.Template, error) {
paths, err := dir.FindFilesWithExtensions(s.userTemplatesPath, "yml", "yaml")
if err != nil {
return nil, errors.Wrap(err, "failed to get paths")
}
- res := make([]alert.Template, 0, len(paths))
+ res := make([]*models.Template, 0, len(paths))
for _, path := range paths {
if ctx.Err() != nil {
return nil, ctx.Err()
@@ -300,89 +268,39 @@ func (s *Service) loadTemplatesFromUserFiles(ctx context.Context) ([]alert.Templ
}
for _, t := range templates {
- if err = validateUserTemplate(&t); err != nil { //nolint:gosec
+ t := t
+ if err = validateUserTemplate(&t); err != nil {
s.l.Warnf("%s %s", path, err)
continue
}
- res = append(res, t)
+ tm, err := models.ConvertTemplate(&t, models.UserFileSource)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to convert alert rule template")
+ }
+
+ res = append(res, tm)
}
}
return res, nil
}
-func (s *Service) loadTemplatesFromDB() ([]TemplateInfo, error) {
- var templates []models.Template
- e := s.db.InTransaction(func(tx *reform.TX) error {
+func (s *Service) loadTemplatesFromDB() ([]*models.Template, error) {
+ var templates []*models.Template
+ errTx := s.db.InTransaction(func(tx *reform.TX) error {
var err error
templates, err = models.FindTemplates(tx.Querier)
return err
})
- if e != nil {
- return nil, errors.Wrap(e, "failed to load rule templates from DB")
+ if errTx != nil {
+ return nil, errors.Wrap(errTx, "failed to load rule templates from DB")
}
- res := make([]TemplateInfo, 0, len(templates))
- for _, t := range templates {
- t := t
- params := make([]alert.Parameter, 0, len(t.Params))
- for _, param := range t.Params {
- p := alert.Parameter{
- Name: param.Name,
- Summary: param.Summary,
- Unit: alert.Unit(param.Unit),
- Type: alert.Type(param.Type),
- }
-
- if alert.Type(param.Type) == alert.Float {
- f := param.FloatParam
-
- if f.Default != nil {
- p.Value = *f.Default
- }
-
- if f.Min != nil && f.Max != nil {
- p.Range = []interface{}{*f.Min, *f.Max}
- }
- }
-
- params = append(params, p)
- }
-
- labels, err := t.GetLabels()
- if err != nil {
- return nil, errors.Wrap(err, "failed to load template labels")
- }
-
- annotations, err := t.GetAnnotations()
- if err != nil {
- return nil, errors.Wrap(err, "failed to load template annotations")
- }
-
- res = append(res,
- TemplateInfo{
- Template: alert.Template{
- Name: t.Name,
- Version: t.Version,
- Summary: t.Summary,
- Expr: t.Expr,
- Params: params,
- For: promconfig.Duration(t.For),
- Severity: common.Severity(t.Severity),
- Labels: labels,
- Annotations: annotations,
- },
- Yaml: t.Yaml,
- Source: convertSource(t.Source),
- CreatedAt: &t.CreatedAt,
- },
- )
- }
- return res, nil
+ return templates, nil
}
// downloadTemplates downloads Percona Alerting templates from Percona Portal.
-func (s *Service) downloadTemplates(ctx context.Context) ([]alert.Template, error) {
+func (s *Service) downloadTemplates(ctx context.Context) ([]*models.Template, error) {
settings, err := models.GetSettings(s.db)
if err != nil {
return nil, err
@@ -415,7 +333,17 @@ func (s *Service) downloadTemplates(ctx context.Context) ([]alert.Template, erro
return nil, err
}
- return templates, nil
+ res := make([]*models.Template, 0, len(templates))
+ for _, t := range templates {
+ t := t
+ tm, err := models.ConvertTemplate(&t, models.SAASSource)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to convert alert rule template")
+ }
+ res = append(res, tm)
+ }
+
+ return res, nil
}
// validateUserTemplate validates user-provided template (API or file).
@@ -468,14 +396,19 @@ func convertSource(source models.Source) alerting.TemplateSource {
}
}
-func convertParamType(t alert.Type) alerting.ParamType {
- // TODO: add another types.
+func convertParamType(t models.ParamType) alerting.ParamType {
switch t {
- case alert.Float:
+ case models.Float:
return alerting.ParamType_FLOAT
- default:
- return alerting.ParamType_PARAM_TYPE_INVALID
+ case models.Bool:
+ return alerting.ParamType_BOOL
+ case models.String:
+ return alerting.ParamType_STRING
}
+
+ // do not add `default:` to make exhaustive linter do its job
+
+ return alerting.ParamType_PARAM_TYPE_INVALID
}
// ListTemplates returns a list of all collected Alert Rule Templates.
@@ -562,32 +495,34 @@ func (s *Service) CreateTemplate(ctx context.Context, req *alerting.CreateTempla
templates, err := alert.Parse(strings.NewReader(req.Yaml), pParams)
if err != nil {
s.l.Errorf("failed to parse rule template form request: +%v", err)
- return nil, status.Error(codes.InvalidArgument, "Failed to parse rule template.")
- }
-
- if len(templates) != 1 {
- return nil, status.Error(codes.InvalidArgument, "Request should contain exactly one rule template.")
+ return nil, status.Errorf(codes.InvalidArgument, "Failed to parse rule template: %v.", err)
}
+ uniqueNames := make(map[string]struct{}, len(templates))
for _, t := range templates {
+ if _, ok := uniqueNames[t.Name]; ok {
+ return nil, status.Errorf(codes.InvalidArgument, "Template with name '%s' declared more that once.", t.Name)
+ }
+ uniqueNames[t.Name] = struct{}{}
if err = validateUserTemplate(&t); err != nil { //nolint:gosec
return nil, status.Errorf(codes.InvalidArgument, "%s.", err)
}
}
- params := &models.CreateTemplateParams{
- Template: &templates[0],
- Yaml: req.Yaml,
- Source: models.UserAPISource,
- }
-
- e := s.db.InTransaction(func(tx *reform.TX) error {
- var err error
- _, err = models.CreateTemplate(tx.Querier, params)
- return err
+ errTx := s.db.InTransaction(func(tx *reform.TX) error {
+ for _, t := range templates {
+ t := t
+ if _, err = models.CreateTemplate(tx.Querier, &models.CreateTemplateParams{
+ Template: &t,
+ Source: models.UserAPISource,
+ }); err != nil {
+ return err
+ }
+ }
+ return nil
})
- if e != nil {
- return nil, e
+ if errTx != nil {
+ return nil, errTx
}
s.CollectTemplates(ctx)
@@ -630,7 +565,6 @@ func (s *Service) UpdateTemplate(ctx context.Context, req *alerting.UpdateTempla
changeParams := &models.ChangeTemplateParams{
Template: &tmpl,
Name: req.Name,
- Yaml: req.Yaml,
}
e := s.db.InTransaction(func(tx *reform.TX) error {
@@ -670,37 +604,38 @@ func (s *Service) DeleteTemplate(ctx context.Context, req *alerting.DeleteTempla
return &alerting.DeleteTemplateResponse{}, nil
}
-func convertTemplate(l *logrus.Entry, template TemplateInfo) (*alerting.Template, error) {
- var err error
+func convertTemplate(l *logrus.Entry, template models.Template) (*alerting.Template, error) {
+ labels, err := template.GetLabels()
+ if err != nil {
+ return nil, errors.WithStack(err)
+ }
+ annotations, err := template.GetAnnotations()
+ if err != nil {
+ return nil, errors.WithStack(err)
+ }
+
t := &alerting.Template{
Name: template.Name,
Summary: template.Summary,
Expr: template.Expr,
- Params: make([]*alerting.ParamDefinition, 0, len(template.Params)),
- For: durationpb.New(time.Duration(template.For)),
+ Params: convertParamDefinitions(l, template.Params),
+ For: durationpb.New(template.For),
Severity: managementpb.Severity(template.Severity),
- Labels: template.Labels,
- Annotations: template.Annotations,
- Source: template.Source,
+ Labels: labels,
+ Annotations: annotations,
+ Source: convertSource(template.Source),
Yaml: template.Yaml,
}
- if template.CreatedAt != nil {
- t.CreatedAt = timestamppb.New(*template.CreatedAt)
- if err = t.CreatedAt.CheckValid(); err != nil {
- return nil, err
- }
- }
-
- t.Params, err = convertParamDefinitions(l, template.Params)
- if err != nil {
+ t.CreatedAt = timestamppb.New(template.CreatedAt)
+ if err = t.CreatedAt.CheckValid(); err != nil {
return nil, err
}
return t, nil
}
-func convertParamDefinitions(l *logrus.Entry, params []alert.Parameter) ([]*alerting.ParamDefinition, error) {
+func convertParamDefinitions(l *logrus.Entry, params models.AlertExprParamsDefinitions) []*alerting.ParamDefinition {
res := make([]*alerting.ParamDefinition, 0, len(params))
for _, p := range params {
pd := &alerting.ParamDefinition{
@@ -710,37 +645,37 @@ func convertParamDefinitions(l *logrus.Entry, params []alert.Parameter) ([]*aler
Type: convertParamType(p.Type),
}
- var err error
switch p.Type {
- case alert.Float:
+ case models.Float:
var fp alerting.FloatParamDefinition
- if p.Value != nil {
- fp.Default, err = p.GetValueForFloat()
- if err != nil {
- return nil, errors.Wrap(err, "failed to get value for float parameter")
+ if p.FloatParam != nil {
+ if p.FloatParam.Default != nil {
+ fp.Default = *p.FloatParam.Default
+ fp.HasDefault = true
+ }
+
+ if p.FloatParam.Min != nil {
+ fp.Min = *p.FloatParam.Min
+ fp.HasMin = true
}
- fp.HasDefault = true
- }
- if len(p.Range) != 0 {
- fp.Min, fp.Max, err = p.GetRangeForFloat()
- if err != nil {
- return nil, errors.Wrap(err, "failed to get range for float parameter")
+ if p.FloatParam.Max != nil {
+ fp.Max = *p.FloatParam.Max
+ fp.HasMax = true
}
- fp.HasMin, fp.HasMax = true, true
}
pd.Value = &alerting.ParamDefinition_Float{Float: &fp}
res = append(res, pd)
- case alert.Bool, alert.String:
+ case models.Bool, models.String:
l.Warnf("Skipping unsupported parameter type %q.", p.Type)
}
// do not add `default:` to make exhaustive linter do its job
}
- return res, nil
+ return res
}
// CreateRule creates alert rule from the given template.
@@ -781,21 +716,16 @@ func (s *Service) CreateRule(ctx context.Context, req *alerting.CreateRuleReques
return nil, status.Errorf(codes.NotFound, "Unknown template %s.", req.TemplateName)
}
- paramsDefinitions, err := models.ConvertParamsDefinitions(template.Params)
- if err != nil {
- return nil, err
- }
-
paramsValues, err := convertParamsValuesToModel(req.Params)
if err != nil {
return nil, err
}
- if err := validateParameters(paramsDefinitions, paramsValues); err != nil {
+ if err := validateParameters(template.Params, paramsValues); err != nil {
return nil, err
}
- forDuration := time.Duration(template.For)
+ forDuration := template.For
if req.For != nil {
forDuration = req.For.AsDuration()
}
@@ -816,9 +746,14 @@ func (s *Service) CreateRule(ctx context.Context, req *alerting.CreateRuleReques
}
}
+ ta, err := template.GetAnnotations()
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to get template annotations")
+ }
+
// Copy annotations form template
annotations := make(map[string]string)
- if err = transformMaps(template.Annotations, annotations, paramsValues.AsStringMap()); err != nil {
+ if err = transformMaps(ta, annotations, paramsValues.AsStringMap()); err != nil {
return nil, errors.Wrap(err, "failed to fill template annotations placeholders")
}
@@ -828,8 +763,13 @@ func (s *Service) CreateRule(ctx context.Context, req *alerting.CreateRuleReques
return nil, errors.Wrap(err, "failed to fill rule labels placeholders")
}
+ tl, err := template.GetLabels()
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to get template labels")
+ }
+
// Add rule labels
- if err = transformMaps(template.Labels, labels, paramsValues.AsStringMap()); err != nil {
+ if err = transformMaps(tl, labels, paramsValues.AsStringMap()); err != nil {
return nil, errors.Wrap(err, "failed to fill template labels placeholders")
}
@@ -914,11 +854,11 @@ func transformMaps(src map[string]string, dest map[string]string, data map[strin
return nil
}
-func convertParamUnit(u alert.Unit) alerting.ParamUnit {
+func convertParamUnit(u models.ParamUnit) alerting.ParamUnit {
switch u {
- case alert.Percentage:
+ case models.Percent:
return alerting.ParamUnit_PERCENTAGE
- case alert.Seconds:
+ case models.Seconds:
return alerting.ParamUnit_SECONDS
}
diff --git a/managed/services/management/alerting/service_test.go b/managed/services/management/alerting/service_test.go
index 9f69f8745d..08bc38d10d 100644
--- a/managed/services/management/alerting/service_test.go
+++ b/managed/services/management/alerting/service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/annotation.go b/managed/services/management/annotation.go
index 1888130b33..26222cf541 100644
--- a/managed/services/management/annotation.go
+++ b/managed/services/management/annotation.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/annotation_test.go b/managed/services/management/annotation_test.go
index b44129379f..977a278ae4 100644
--- a/managed/services/management/annotation_test.go
+++ b/managed/services/management/annotation_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -30,9 +30,9 @@ import (
"github.com/percona/pmm/api/managementpb"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
func TestAnnotations(t *testing.T) {
diff --git a/managed/services/management/azure_database.go b/managed/services/management/azure_database.go
index 0db8ebbb8d..dda84b4fae 100644
--- a/managed/services/management/azure_database.go
+++ b/managed/services/management/azure_database.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -30,7 +30,7 @@ import (
azurev1beta1 "github.com/percona/pmm/api/managementpb/azure"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
)
const (
diff --git a/managed/services/management/backup/artifacts_service.go b/managed/services/management/backup/artifacts_service.go
index e278f6dc34..3f4d212dfc 100644
--- a/managed/services/management/backup/artifacts_service.go
+++ b/managed/services/management/backup/artifacts_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/backup/artifacts_service_test.go b/managed/services/management/backup/artifacts_service_test.go
index 9dddfd29ae..a60afc3fe6 100644
--- a/managed/services/management/backup/artifacts_service_test.go
+++ b/managed/services/management/backup/artifacts_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/backup/backups_service.go b/managed/services/management/backup/backups_service.go
index d8fc1ea025..73601293fc 100644
--- a/managed/services/management/backup/backups_service.go
+++ b/managed/services/management/backup/backups_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -124,7 +124,7 @@ func (s *BackupsService) StartBackup(ctx context.Context, req *backuppb.StartBac
Folder: req.Folder,
})
if err != nil {
- return nil, convertBackupError(err)
+ return nil, convertError(err)
}
return &backuppb.StartBackupResponse{
@@ -154,7 +154,7 @@ func (s *BackupsService) RestoreBackup(
id, err := s.backupService.RestoreBackup(ctx, req.ServiceId, req.ArtifactId, req.PitrTimestamp.AsTime())
if err != nil {
- return nil, convertRestoreBackupError(err)
+ return nil, convertError(err)
}
return &backuppb.RestoreBackupResponse{
@@ -253,7 +253,7 @@ func (s *BackupsService) ScheduleBackup(ctx context.Context, req *backuppb.Sched
StartAt: t,
})
if err != nil {
- return convertModelError(err)
+ return convertError(err)
}
id = scheduledTask.ID
@@ -328,7 +328,7 @@ func (s *BackupsService) ChangeScheduledBackup(ctx context.Context, req *backupp
errTx := s.db.InTransactionContext(ctx, nil, func(tx *reform.TX) error {
scheduledTask, err := models.FindScheduledTaskByID(tx.Querier, req.ScheduledBackupId)
if err != nil {
- return convertModelError(err)
+ return convertError(err)
}
var data *models.CommonBackupTaskData
@@ -381,7 +381,7 @@ func (s *BackupsService) ChangeScheduledBackup(ctx context.Context, req *backupp
err = s.scheduleService.Update(req.ScheduledBackupId, params)
- return convertModelError(err)
+ return convertError(err)
})
if errTx != nil {
return nil, errTx
@@ -647,112 +647,58 @@ func convertModelToBackupModel(dataModel backuppb.DataModel) (models.DataModel,
}
}
-func convertBackupError(backupErr error) error {
- if backupErr == nil {
+// convertError converts error from Go to API.
+func convertError(e error) error {
+ if e == nil {
return nil
}
var unsupportedAgentErr *agents.AgentNotSupportedError
- if errors.As(backupErr, &unsupportedAgentErr) {
- return status.Error(codes.FailedPrecondition, backupErr.Error())
+ if errors.As(e, &unsupportedAgentErr) {
+ return status.Error(codes.FailedPrecondition, e.Error())
}
var code backuppb.ErrorCode
switch {
- case errors.Is(backupErr, backup.ErrIncompatibleService):
- return status.Error(codes.FailedPrecondition, backupErr.Error())
- case errors.Is(backupErr, backup.ErrXtrabackupNotInstalled):
+ case errors.Is(e, backup.ErrXtrabackupNotInstalled):
code = backuppb.ErrorCode_ERROR_CODE_XTRABACKUP_NOT_INSTALLED
- case errors.Is(backupErr, backup.ErrInvalidXtrabackup):
+ case errors.Is(e, backup.ErrInvalidXtrabackup):
code = backuppb.ErrorCode_ERROR_CODE_INVALID_XTRABACKUP
- case errors.Is(backupErr, backup.ErrIncompatibleXtrabackup):
+ case errors.Is(e, backup.ErrIncompatibleXtrabackup):
code = backuppb.ErrorCode_ERROR_CODE_INCOMPATIBLE_XTRABACKUP
- case errors.Is(backupErr, backup.ErrIncompatibleLocationType):
- return status.Error(codes.FailedPrecondition, backupErr.Error())
- case errors.Is(backupErr, backup.ErrIncompatiblePBM):
- return status.Error(codes.FailedPrecondition, backupErr.Error())
-
- default:
- return backupErr
- }
-
- st, err := status.New(codes.FailedPrecondition, backupErr.Error()).WithDetails(&backuppb.Error{
- Code: code,
- })
- if err != nil {
- return fmt.Errorf("failed to construct status error: %w, restore error: %w", err, backupErr)
- }
-
- return st.Err()
-}
-
-func convertRestoreBackupError(restoreError error) error {
- if restoreError == nil {
- return nil
- }
-
- var unsupportedAgentErr *agents.AgentNotSupportedError
- if errors.As(restoreError, &unsupportedAgentErr) {
- return status.Error(codes.FailedPrecondition, restoreError.Error())
- }
-
- var code backuppb.ErrorCode
- switch {
- case errors.Is(restoreError, backup.ErrIncompatibleService):
- return status.Error(codes.FailedPrecondition, restoreError.Error())
- case errors.Is(restoreError, backup.ErrXtrabackupNotInstalled):
- code = backuppb.ErrorCode_ERROR_CODE_XTRABACKUP_NOT_INSTALLED
- case errors.Is(restoreError, backup.ErrInvalidXtrabackup):
- code = backuppb.ErrorCode_ERROR_CODE_INVALID_XTRABACKUP
- case errors.Is(restoreError, backup.ErrIncompatibleXtrabackup):
- code = backuppb.ErrorCode_ERROR_CODE_INCOMPATIBLE_XTRABACKUP
- case errors.Is(restoreError, backup.ErrIncompatibleTargetMySQL):
+ case errors.Is(e, backup.ErrIncompatibleTargetMySQL):
code = backuppb.ErrorCode_ERROR_CODE_INCOMPATIBLE_TARGET_MYSQL
- case errors.Is(restoreError, backup.ErrIncompatibleTargetMongoDB):
+ case errors.Is(e, backup.ErrIncompatibleTargetMongoDB):
code = backuppb.ErrorCode_ERROR_CODE_INCOMPATIBLE_TARGET_MONGODB
- case errors.Is(restoreError, backup.ErrTimestampOutOfRange):
- return status.Error(codes.OutOfRange, restoreError.Error())
- case errors.Is(restoreError, backup.ErrIncompatibleArtifactMode):
- return status.Error(codes.FailedPrecondition, restoreError.Error())
- case errors.Is(restoreError, models.ErrNotFound):
- return status.Error(codes.NotFound, restoreError.Error())
- case errors.Is(restoreError, backup.ErrAnotherOperationInProgress):
- return status.Error(codes.FailedPrecondition, restoreError.Error())
- case errors.Is(restoreError, backup.ErrArtifactNotReady):
- return status.Error(codes.FailedPrecondition, restoreError.Error())
- case errors.Is(restoreError, backup.ErrIncompatiblePBM):
- return status.Error(codes.FailedPrecondition, restoreError.Error())
+ case errors.Is(e, backup.ErrTimestampOutOfRange):
+ return status.Error(codes.OutOfRange, e.Error())
+ case errors.Is(e, models.ErrNotFound):
+ return status.Error(codes.NotFound, e.Error())
+ case errors.Is(e, models.ErrAlreadyExists):
+ return status.Error(codes.AlreadyExists, e.Error())
+ case errors.Is(e, backup.ErrAnotherOperationInProgress),
+ errors.Is(e, backup.ErrArtifactNotReady),
+ errors.Is(e, backup.ErrIncompatiblePBM),
+ errors.Is(e, backup.ErrIncompatibleLocationType),
+ errors.Is(e, backup.ErrIncompatibleService),
+ errors.Is(e, backup.ErrIncompatibleArtifactMode),
+ errors.Is(e, services.ErrLocationFolderPairAlreadyUsed):
+ return status.Error(codes.FailedPrecondition, e.Error())
default:
- return restoreError
+ return e
}
- st, err := status.New(codes.FailedPrecondition, restoreError.Error()).WithDetails(&backuppb.Error{
+ st, err := status.New(codes.FailedPrecondition, e.Error()).WithDetails(&backuppb.Error{
Code: code,
})
if err != nil {
- return fmt.Errorf("failed to construct status error: %w, restore error: %w", err, restoreError)
+ return fmt.Errorf("failed to construct status error: %w, original error: %w", err, e)
}
return st.Err()
}
-func convertModelError(modelError error) error {
- if modelError == nil {
- return nil
- }
-
- switch {
- case errors.Is(modelError, models.ErrNotFound):
- return status.Error(codes.NotFound, modelError.Error())
- case errors.Is(modelError, models.ErrAlreadyExists):
- return status.Error(codes.AlreadyExists, modelError.Error())
-
- default:
- return modelError
- }
-}
-
// isFolderSafe checks if specified path is safe against traversal attacks.
func isFolderSafe(path string) error {
if path == "" {
diff --git a/managed/services/management/backup/backups_service_test.go b/managed/services/management/backup/backups_service_test.go
index e1afdd22a0..07fdd1531f 100644
--- a/managed/services/management/backup/backups_service_test.go
+++ b/managed/services/management/backup/backups_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/backup/deps.go b/managed/services/management/backup/deps.go
index 5b8b794122..a8493dbe7a 100644
--- a/managed/services/management/backup/deps.go
+++ b/managed/services/management/backup/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/backup/locations_service.go b/managed/services/management/backup/locations_service.go
index 9b64c835e6..a81dca8aa0 100644
--- a/managed/services/management/backup/locations_service.go
+++ b/managed/services/management/backup/locations_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/backup/locations_service_test.go b/managed/services/management/backup/locations_service_test.go
index 00bcb2108c..b8e39f107a 100644
--- a/managed/services/management/backup/locations_service_test.go
+++ b/managed/services/management/backup/locations_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/backup/mock_aws_s3_test.go b/managed/services/management/backup/mock_aws_s3_test.go
index 967f65a60a..5d49f8e9c8 100644
--- a/managed/services/management/backup/mock_aws_s3_test.go
+++ b/managed/services/management/backup/mock_aws_s3_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/management/backup/mock_backup_service_test.go b/managed/services/management/backup/mock_backup_service_test.go
index e48d837367..c90ef292e7 100644
--- a/managed/services/management/backup/mock_backup_service_test.go
+++ b/managed/services/management/backup/mock_backup_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/management/backup/mock_pbm_pitr_service_test.go b/managed/services/management/backup/mock_pbm_pitr_service_test.go
index 0200781289..d7e4af696b 100644
--- a/managed/services/management/backup/mock_pbm_pitr_service_test.go
+++ b/managed/services/management/backup/mock_pbm_pitr_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/management/backup/mock_removal_service_test.go b/managed/services/management/backup/mock_removal_service_test.go
index 220e042193..cca93d0566 100644
--- a/managed/services/management/backup/mock_removal_service_test.go
+++ b/managed/services/management/backup/mock_removal_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/management/backup/mock_schedule_service_test.go b/managed/services/management/backup/mock_schedule_service_test.go
index 21c17c231b..f9cd4fe2c4 100644
--- a/managed/services/management/backup/mock_schedule_service_test.go
+++ b/managed/services/management/backup/mock_schedule_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package backup
diff --git a/managed/services/management/backup/restore_history_service.go b/managed/services/management/backup/restore_history_service.go
index e54ee8c95a..1c901fc5d6 100644
--- a/managed/services/management/backup/restore_history_service.go
+++ b/managed/services/management/backup/restore_history_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/checks.go b/managed/services/management/checks.go
index 4589c6ee14..d1d8049c2b 100644
--- a/managed/services/management/checks.go
+++ b/managed/services/management/checks.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -122,17 +122,23 @@ func (s *ChecksAPIService) GetFailedChecks(ctx context.Context, req *managementp
failedChecks := make([]*managementpb.CheckResult, 0, len(results))
for _, result := range results {
+ labels := make(map[string]string, len(result.Target.Labels)+len(result.Result.Labels))
+ for k, v := range result.Result.Labels {
+ labels[k] = v
+ }
+ for k, v := range result.Target.Labels {
+ labels[k] = v
+ }
+
failedChecks = append(failedChecks, &managementpb.CheckResult{
Summary: result.Result.Summary,
CheckName: result.CheckName,
Description: result.Result.Description,
ReadMoreUrl: result.Result.ReadMoreURL,
Severity: managementpb.Severity(result.Result.Severity),
- Labels: result.Result.Labels,
+ Labels: labels,
ServiceName: result.Target.ServiceName,
ServiceId: result.Target.ServiceID,
- AlertId: result.AlertID,
- Silenced: result.Silenced,
})
}
@@ -167,12 +173,7 @@ func (s *ChecksAPIService) GetFailedChecks(ctx context.Context, req *managementp
// ToggleCheckAlert toggles the silence state of the check with the provided alertID.
func (s *ChecksAPIService) ToggleCheckAlert(ctx context.Context, req *managementpb.ToggleCheckAlertRequest) (*managementpb.ToggleCheckAlertResponse, error) {
- err := s.checksService.ToggleCheckAlert(ctx, req.AlertId, req.Silence)
- if err != nil {
- return nil, errors.Wrapf(err, "failed to toggle silence status of alert with id: %s", req.AlertId)
- }
-
- return &managementpb.ToggleCheckAlertResponse{}, nil
+ return nil, status.Error(codes.NotFound, "Advisor alerts silencing is not supported anymore.")
}
// GetSecurityCheckResults returns Security Thread Tool's latest checks results.
@@ -240,6 +241,7 @@ func (s *ChecksAPIService) ListSecurityChecks(_ context.Context, _ *managementpb
Name: c.Name,
Disabled: disabled,
Summary: c.Summary,
+ Family: convertFamily(c.GetFamily()),
Description: c.Description,
Interval: convertInterval(c.Interval),
})
@@ -273,6 +275,7 @@ func (s *ChecksAPIService) ListAdvisors(_ context.Context, _ *managementpb.ListA
Name: c.Name,
Disabled: disabled,
Summary: c.Summary,
+ Family: convertFamily(c.GetFamily()),
Description: c.Description,
Interval: convertInterval(c.Interval),
})
@@ -282,7 +285,7 @@ func (s *ChecksAPIService) ListAdvisors(_ context.Context, _ *managementpb.ListA
Name: a.Name,
Description: a.Description,
Summary: a.Summary,
- Comment: createComment(s.l, a.Checks),
+ Comment: createComment(a.Checks),
Category: a.Category,
Checks: checks,
})
@@ -291,22 +294,27 @@ func (s *ChecksAPIService) ListAdvisors(_ context.Context, _ *managementpb.ListA
return &managementpb.ListAdvisorsResponse{Advisors: res}, nil
}
-func createComment(l *logrus.Entry, checks []check.Check) string {
- checksM := make(map[string]check.Check, len(checks))
+func createComment(checks []check.Check) string {
+ var mySQL, postgreSQL, mongoDB bool
for _, c := range checks {
- checksM[c.Name] = c
+ switch c.GetFamily() {
+ case check.MySQL:
+ mySQL = true
+ case check.PostgreSQL:
+ postgreSQL = true
+ case check.MongoDB:
+ mongoDB = true
+ }
}
- mysqlChecks, portgreSQLChecks, mongoDBChecks := services.GroupChecksByDB(l, checksM)
-
b := make([]string, 0, 3)
- if len(mysqlChecks) != 0 {
+ if mySQL {
b = append(b, "MySQL")
}
- if len(portgreSQLChecks) != 0 {
+ if postgreSQL {
b = append(b, "PostgreSQL")
}
- if len(mongoDBChecks) != 0 {
+ if mongoDB {
b = append(b, "MongoDB")
}
@@ -377,6 +385,20 @@ func convertInterval(interval check.Interval) managementpb.SecurityCheckInterval
}
}
+// convertFamily converts check.Family type to managementpb.AdvisorCheckFamily.
+func convertFamily(family check.Family) managementpb.AdvisorCheckFamily {
+ switch family {
+ case check.MySQL:
+ return managementpb.AdvisorCheckFamily_ADVISOR_CHECK_FAMILY_MYSQL
+ case check.PostgreSQL:
+ return managementpb.AdvisorCheckFamily_ADVISOR_CHECK_FAMILY_POSTGRESQL
+ case check.MongoDB:
+ return managementpb.AdvisorCheckFamily_ADVISOR_CHECK_FAMILY_MONGODB
+ default:
+ return managementpb.AdvisorCheckFamily_ADVISOR_CHECK_FAMILY_INVALID
+ }
+}
+
// convertAPIInterval converts managementpb.SecurityCheckInterval type to check.Interval.
func convertAPIInterval(interval managementpb.SecurityCheckInterval) (check.Interval, error) {
switch interval {
diff --git a/managed/services/management/checks_test.go b/managed/services/management/checks_test.go
index d630910ffc..bd2e5697d1 100644
--- a/managed/services/management/checks_test.go
+++ b/managed/services/management/checks_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -23,7 +23,6 @@ import (
"github.com/percona-platform/saas/pkg/check"
"github.com/percona-platform/saas/pkg/common"
"github.com/pkg/errors"
- "github.com/sirupsen/logrus"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
@@ -465,8 +464,6 @@ func TestUpdateSecurityChecks(t *testing.T) {
func TestCreateComment(t *testing.T) {
t.Parallel()
- l := logrus.WithField("component", "tests")
-
testCases := []struct {
Name string
Comment string
@@ -502,7 +499,7 @@ func TestCreateComment(t *testing.T) {
t.Run(tc.Name, func(t *testing.T) {
t.Parallel()
- assert.Equal(t, tc.Comment, createComment(l, tc.Checks))
+ assert.Equal(t, tc.Comment, createComment(tc.Checks))
})
}
}
diff --git a/managed/services/management/common/common.go b/managed/services/management/common/common.go
new file mode 100644
index 0000000000..9697e70451
--- /dev/null
+++ b/managed/services/management/common/common.go
@@ -0,0 +1,126 @@
+// Copyright (C) 2023 Percona LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+// Package common contains common and cross-service logics.
+package common
+
+import (
+ "context"
+
+ "github.com/pkg/errors"
+ "gopkg.in/reform.v1"
+
+ backuppb "github.com/percona/pmm/api/managementpb/backup"
+ "github.com/percona/pmm/managed/models"
+ managementbackup "github.com/percona/pmm/managed/services/management/backup"
+)
+
+// ErrClusterLocked is returned when there is an unfinished job that doesn't allow to change service cluster name.
+var ErrClusterLocked = errors.New("cluster/service is locked")
+
+type MgmtServices struct {
+ BackupsService *managementbackup.BackupsService
+ ArtifactsService *managementbackup.ArtifactsService
+ RestoreHistoryService *managementbackup.RestoreHistoryService
+}
+
+// RemoveScheduledTasks removes scheduled backup tasks and check there are no running backup/restore tasks in case user changes service cluster label.
+func (s *MgmtServices) RemoveScheduledTasks(ctx context.Context, db *reform.DB, params *models.ChangeStandardLabelsParams) error {
+ if params.Cluster == nil {
+ return nil
+ }
+
+ service, err := models.FindServiceByID(db.Querier, params.ServiceID)
+ if err != nil {
+ return err
+ }
+
+ var servicesInCurrentCluster, servicesInNewCluster []*models.Service
+
+ if service.Cluster != "" {
+ servicesInCurrentCluster, err = models.FindServices(db.Querier, models.ServiceFilters{Cluster: service.Cluster})
+ if err != nil {
+ return err
+ }
+ }
+
+ if *params.Cluster != "" {
+ servicesInNewCluster, err = models.FindServices(db.Querier, models.ServiceFilters{Cluster: *params.Cluster})
+ if err != nil {
+ return err
+ }
+ }
+
+ allServices := append(servicesInCurrentCluster, servicesInNewCluster...) //nolint:gocritic
+ allServices = append(allServices, service)
+
+ sMap := make(map[string]struct{})
+ for _, service := range allServices {
+ sMap[service.ServiceID] = struct{}{}
+ }
+
+ scheduledTasks, err := s.BackupsService.ListScheduledBackups(ctx, &backuppb.ListScheduledBackupsRequest{})
+ if err != nil {
+ return err
+ }
+
+ // Remove scheduled tasks.
+ for _, task := range scheduledTasks.ScheduledBackups {
+ if _, ok := sMap[task.ServiceId]; ok {
+ _, err = s.BackupsService.RemoveScheduledBackup(ctx, &backuppb.RemoveScheduledBackupRequest{ScheduledBackupId: task.ScheduledBackupId})
+ if err != nil {
+ return err
+ }
+ }
+ }
+
+ // Check no backup tasks running.
+ artifacts, err := s.ArtifactsService.ListArtifacts(ctx, &backuppb.ListArtifactsRequest{})
+ if err != nil {
+ return err
+ }
+
+ statusNotFinal := func(status backuppb.BackupStatus) bool {
+ switch status {
+ case
+ backuppb.BackupStatus_BACKUP_STATUS_IN_PROGRESS,
+ backuppb.BackupStatus_BACKUP_STATUS_PENDING,
+ backuppb.BackupStatus_BACKUP_STATUS_PAUSED:
+ return true
+ default:
+ return false
+ }
+ }
+
+ for _, artifact := range artifacts.Artifacts {
+ if _, ok := sMap[artifact.ServiceId]; ok && statusNotFinal(artifact.Status) {
+ return errors.Wrapf(ErrClusterLocked, "there is an unfinished backup job for service %s or other service in the same cluster", service.ServiceID)
+ }
+ }
+
+ // Check no restore tasks running.
+ restores, err := s.RestoreHistoryService.ListRestoreHistory(ctx, &backuppb.ListRestoreHistoryRequest{})
+ if err != nil {
+ return err
+ }
+
+ for _, restoreItem := range restores.Items {
+ if _, ok := sMap[restoreItem.ServiceId]; ok && restoreItem.Status == backuppb.RestoreStatus_RESTORE_STATUS_IN_PROGRESS {
+ return errors.Wrapf(ErrClusterLocked, "there is an unfinished restore job for service %s or other service in the same cluster", service.ServiceID)
+ }
+ }
+
+ return nil
+}
diff --git a/managed/services/management/dbaas/components_service.go b/managed/services/management/dbaas/components_service.go
index ffa549968a..e33497aabe 100644
--- a/managed/services/management/dbaas/components_service.go
+++ b/managed/services/management/dbaas/components_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/components_service_test.go b/managed/services/management/dbaas/components_service_test.go
index 5680fe59bd..3a8198301c 100644
--- a/managed/services/management/dbaas/components_service_test.go
+++ b/managed/services/management/dbaas/components_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -36,9 +36,9 @@ import (
dbaasv1beta1 "github.com/percona/pmm/api/managementpb/dbaas"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
pmmversion "github.com/percona/pmm/version"
)
diff --git a/managed/services/management/dbaas/db_cluster_service.go b/managed/services/management/dbaas/db_cluster_service.go
index 3746727b5c..fd42534e5e 100644
--- a/managed/services/management/dbaas/db_cluster_service.go
+++ b/managed/services/management/dbaas/db_cluster_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/db_cluster_service_test.go b/managed/services/management/dbaas/db_cluster_service_test.go
index 560b8c8ad0..8afa320443 100644
--- a/managed/services/management/dbaas/db_cluster_service_test.go
+++ b/managed/services/management/dbaas/db_cluster_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -34,9 +34,9 @@ import (
dbaasv1beta1 "github.com/percona/pmm/api/managementpb/dbaas"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
const dbKubeconfigTest = `
diff --git a/managed/services/management/dbaas/dbaas_initializer.go b/managed/services/management/dbaas/dbaas_initializer.go
index f8b10b6529..155570e388 100644
--- a/managed/services/management/dbaas/dbaas_initializer.go
+++ b/managed/services/management/dbaas/dbaas_initializer.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/deps.go b/managed/services/management/dbaas/deps.go
index 84509c0236..3f9be6d5f5 100644
--- a/managed/services/management/dbaas/deps.go
+++ b/managed/services/management/dbaas/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/kube_clients.go b/managed/services/management/dbaas/kube_clients.go
index c6328b4f06..305cf55c7e 100644
--- a/managed/services/management/dbaas/kube_clients.go
+++ b/managed/services/management/dbaas/kube_clients.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/kubeconfig_test.go b/managed/services/management/dbaas/kubeconfig_test.go
index 4e71660870..670ae780f3 100644
--- a/managed/services/management/dbaas/kubeconfig_test.go
+++ b/managed/services/management/dbaas/kubeconfig_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/kubernetes_server.go b/managed/services/management/dbaas/kubernetes_server.go
index fcb9ed9aa6..5a72cb79e5 100644
--- a/managed/services/management/dbaas/kubernetes_server.go
+++ b/managed/services/management/dbaas/kubernetes_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/kubernetes_server_test.go b/managed/services/management/dbaas/kubernetes_server_test.go
index 7a2ea1640b..5794a27d41 100644
--- a/managed/services/management/dbaas/kubernetes_server_test.go
+++ b/managed/services/management/dbaas/kubernetes_server_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -40,9 +40,9 @@ import (
dbaasv1beta1 "github.com/percona/pmm/api/managementpb/dbaas"
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services/dbaas/kubernetes"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
pmmversion "github.com/percona/pmm/version"
)
diff --git a/managed/services/management/dbaas/logs_service.go b/managed/services/management/dbaas/logs_service.go
index 6cef57780c..0609f58d7a 100644
--- a/managed/services/management/dbaas/logs_service.go
+++ b/managed/services/management/dbaas/logs_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/mock_components_service_test.go b/managed/services/management/dbaas/mock_components_service_test.go
index 4e8c1662a6..7e61ec0790 100644
--- a/managed/services/management/dbaas/mock_components_service_test.go
+++ b/managed/services/management/dbaas/mock_components_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package dbaas
diff --git a/managed/services/management/dbaas/mock_dbaas_client_test.go b/managed/services/management/dbaas/mock_dbaas_client_test.go
index 6908f7c2c4..56055f83e4 100644
--- a/managed/services/management/dbaas/mock_dbaas_client_test.go
+++ b/managed/services/management/dbaas/mock_dbaas_client_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package dbaas
diff --git a/managed/services/management/dbaas/mock_grafana_client_test.go b/managed/services/management/dbaas/mock_grafana_client_test.go
index c74aa84637..e6c5cc9565 100644
--- a/managed/services/management/dbaas/mock_grafana_client_test.go
+++ b/managed/services/management/dbaas/mock_grafana_client_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package dbaas
diff --git a/managed/services/management/dbaas/mock_kube_storage_manager_test.go b/managed/services/management/dbaas/mock_kube_storage_manager_test.go
index e5f2f146a1..45cf143e0c 100644
--- a/managed/services/management/dbaas/mock_kube_storage_manager_test.go
+++ b/managed/services/management/dbaas/mock_kube_storage_manager_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package dbaas
diff --git a/managed/services/management/dbaas/mock_kubernetes_client_test.go b/managed/services/management/dbaas/mock_kubernetes_client_test.go
index 2dd1b630f0..c4b9e38d31 100644
--- a/managed/services/management/dbaas/mock_kubernetes_client_test.go
+++ b/managed/services/management/dbaas/mock_kubernetes_client_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package dbaas
diff --git a/managed/services/management/dbaas/mock_version_service_test.go b/managed/services/management/dbaas/mock_version_service_test.go
index b5da686a14..cba073721d 100644
--- a/managed/services/management/dbaas/mock_version_service_test.go
+++ b/managed/services/management/dbaas/mock_version_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package dbaas
diff --git a/managed/services/management/dbaas/psmdb_cluster_service.go b/managed/services/management/dbaas/psmdb_cluster_service.go
index 66365ae9b9..7a9fdea706 100644
--- a/managed/services/management/dbaas/psmdb_cluster_service.go
+++ b/managed/services/management/dbaas/psmdb_cluster_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/psmdb_cluster_service_test.go b/managed/services/management/dbaas/psmdb_cluster_service_test.go
index 9d51595017..b406675433 100644
--- a/managed/services/management/dbaas/psmdb_cluster_service_test.go
+++ b/managed/services/management/dbaas/psmdb_cluster_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -36,9 +36,9 @@ import (
dbaasv1beta1 "github.com/percona/pmm/api/managementpb/dbaas"
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services/dbaas/kubernetes"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
pmmversion "github.com/percona/pmm/version"
)
diff --git a/managed/services/management/dbaas/pxc_cluster_service.go b/managed/services/management/dbaas/pxc_cluster_service.go
index e9b007a197..de510c9998 100644
--- a/managed/services/management/dbaas/pxc_cluster_service.go
+++ b/managed/services/management/dbaas/pxc_cluster_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/pxc_cluster_service_test.go b/managed/services/management/dbaas/pxc_cluster_service_test.go
index ed2e747f19..d5da41acfd 100644
--- a/managed/services/management/dbaas/pxc_cluster_service_test.go
+++ b/managed/services/management/dbaas/pxc_cluster_service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -39,9 +39,9 @@ import (
dbaasv1beta1 "github.com/percona/pmm/api/managementpb/dbaas"
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services/dbaas/kubernetes"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
pmmversion "github.com/percona/pmm/version"
)
diff --git a/managed/services/management/dbaas/template_service.go b/managed/services/management/dbaas/template_service.go
index 527e667857..8680164533 100644
--- a/managed/services/management/dbaas/template_service.go
+++ b/managed/services/management/dbaas/template_service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/version_service_client.go b/managed/services/management/dbaas/version_service_client.go
index db0fb82cb7..934d9bebba 100644
--- a/managed/services/management/dbaas/version_service_client.go
+++ b/managed/services/management/dbaas/version_service_client.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/dbaas/version_service_client_test.go b/managed/services/management/dbaas/version_service_client_test.go
index 3eb41bff61..fed2e3037e 100644
--- a/managed/services/management/dbaas/version_service_client_test.go
+++ b/managed/services/management/dbaas/version_service_client_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/deps.go b/managed/services/management/deps.go
index 1a873f89a4..9849a0c2f6 100644
--- a/managed/services/management/deps.go
+++ b/managed/services/management/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -71,7 +71,6 @@ type checksService interface {
DisableChecks(checkNames []string) error
EnableChecks(checkNames []string) error
ChangeInterval(params map[string]check.Interval) error
- ToggleCheckAlert(ctx context.Context, alertID string, newStatus bool) error
}
// grafanaClient is a subset of methods of grafana.Client used by this package.
diff --git a/managed/services/management/external.go b/managed/services/management/external.go
index 933e02d990..7bb3253f8c 100644
--- a/managed/services/management/external.go
+++ b/managed/services/management/external.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/grpc/actions_server.go b/managed/services/management/grpc/actions_server.go
index 64b59b0b70..b1c2ba947a 100644
--- a/managed/services/management/grpc/actions_server.go
+++ b/managed/services/management/grpc/actions_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -340,7 +340,7 @@ func (s *actionsServer) StartPostgreSQLShowIndexAction(ctx context.Context, req
}, nil
}
-// StartMongoDBExplainAction starts MongoDB Explain action
+// StartMongoDBExplainAction starts MongoDB Explain action.
func (s *actionsServer) StartMongoDBExplainAction(ctx context.Context, req *managementpb.StartMongoDBExplainActionRequest) (
*managementpb.StartMongoDBExplainActionResponse, error,
) {
diff --git a/managed/services/management/grpc/annotation_server.go b/managed/services/management/grpc/annotation_server.go
index ed9da9dea7..47fba492bd 100644
--- a/managed/services/management/grpc/annotation_server.go
+++ b/managed/services/management/grpc/annotation_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/grpc/mongodb_server.go b/managed/services/management/grpc/mongodb_server.go
index c6c3a41091..201b04fd10 100644
--- a/managed/services/management/grpc/mongodb_server.go
+++ b/managed/services/management/grpc/mongodb_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -22,7 +22,7 @@ import (
"github.com/percona/pmm/managed/services/management"
)
-// TODO merge into ../mongodb.go
+// TODO merge into ../mongodb.go.
type mongoDBServer struct {
svc *management.MongoDBService
diff --git a/managed/services/management/grpc/mysql_server.go b/managed/services/management/grpc/mysql_server.go
index 754770bbbc..6753a6c4db 100644
--- a/managed/services/management/grpc/mysql_server.go
+++ b/managed/services/management/grpc/mysql_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -22,7 +22,7 @@ import (
"github.com/percona/pmm/managed/services/management"
)
-// TODO merge into ../mysql.go
+// TODO merge into ../mysql.go.
type mySQLServer struct {
svc *management.MySQLService
diff --git a/managed/services/management/grpc/node_server.go b/managed/services/management/grpc/node_server.go
index 57e54e5a30..1191ee3081 100644
--- a/managed/services/management/grpc/node_server.go
+++ b/managed/services/management/grpc/node_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -22,7 +22,7 @@ import (
"github.com/percona/pmm/managed/services/management"
)
-// TODO merge into ../node.go
+// TODO merge into ../node.go.
type nodeServer struct {
svc *management.NodeService
diff --git a/managed/services/management/grpc/postgresql_server.go b/managed/services/management/grpc/postgresql_server.go
index cad7f99a94..2908045b4c 100644
--- a/managed/services/management/grpc/postgresql_server.go
+++ b/managed/services/management/grpc/postgresql_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -22,7 +22,7 @@ import (
"github.com/percona/pmm/managed/services/management"
)
-// TODO merge into ../postgresql.go
+// TODO merge into ../postgresql.go.
type postgreSQLServer struct {
svc *management.PostgreSQLService
diff --git a/managed/services/management/grpc/proxysql_server.go b/managed/services/management/grpc/proxysql_server.go
index 2394827148..7e8456fbca 100644
--- a/managed/services/management/grpc/proxysql_server.go
+++ b/managed/services/management/grpc/proxysql_server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -22,7 +22,7 @@ import (
"github.com/percona/pmm/managed/services/management"
)
-// TODO merge into ../proxysql.go
+// TODO merge into ../proxysql.go.
type proxySQLServer struct {
svc *management.ProxySQLService
diff --git a/managed/services/management/haproxy.go b/managed/services/management/haproxy.go
index a3763f9749..320b7bd1b5 100644
--- a/managed/services/management/haproxy.go
+++ b/managed/services/management/haproxy.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/ia/deps.go b/managed/services/management/ia/deps.go
deleted file mode 100644
index 12f19bc0a4..0000000000
--- a/managed/services/management/ia/deps.go
+++ /dev/null
@@ -1,48 +0,0 @@
-// Copyright (C) 2017 Percona LLC
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package ia
-
-import (
- "context"
-
- "github.com/percona/pmm/api/alertmanager/ammodels"
- "github.com/percona/pmm/managed/services"
- "github.com/percona/pmm/managed/services/management/alerting"
-)
-
-//go:generate ../../../../bin/mockery --name=alertManager --case=snake --inpackage --testonly
-//go:generate ../../../../bin/mockery --name=vmAlert --case=snake --inpackage --testonly
-//go:generate ../../../../bin/mockery --name=templatesService --case=snake --inpackage --testonly
-
-// alertManager is a subset of methods of alertmanager.Service used by this package.
-// We use it instead of real type for testing and to avoid dependency cycle.
-type alertManager interface {
- GetAlerts(ctx context.Context, params *services.FilterParams) ([]*ammodels.GettableAlert, error)
- FindAlertsByID(ctx context.Context, params *services.FilterParams, ids []string) ([]*ammodels.GettableAlert, error)
- SilenceAlerts(ctx context.Context, alerts []*ammodels.GettableAlert) error
- UnsilenceAlerts(ctx context.Context, alerts []*ammodels.GettableAlert) error
- RequestConfigurationUpdate()
-}
-
-// vmAlert is a subset of methods of vmalert.Service used by this package.
-// We use it instead of real type for testing and to avoid dependency cycle.
-type vmAlert interface {
- RequestConfigurationUpdate()
-}
-
-type templatesService interface {
- GetTemplates() map[string]alerting.TemplateInfo
-}
diff --git a/managed/services/management/ia/mock_alert_manager_test.go b/managed/services/management/ia/mock_alert_manager_test.go
deleted file mode 100644
index 807ea6bb70..0000000000
--- a/managed/services/management/ia/mock_alert_manager_test.go
+++ /dev/null
@@ -1,117 +0,0 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
-
-package ia
-
-import (
- context "context"
-
- mock "github.com/stretchr/testify/mock"
-
- ammodels "github.com/percona/pmm/api/alertmanager/ammodels"
- services "github.com/percona/pmm/managed/services"
-)
-
-// mockAlertManager is an autogenerated mock type for the alertManager type
-type mockAlertManager struct {
- mock.Mock
-}
-
-// FindAlertsByID provides a mock function with given fields: ctx, params, ids
-func (_m *mockAlertManager) FindAlertsByID(ctx context.Context, params *services.FilterParams, ids []string) ([]*ammodels.GettableAlert, error) {
- ret := _m.Called(ctx, params, ids)
-
- var r0 []*ammodels.GettableAlert
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, *services.FilterParams, []string) ([]*ammodels.GettableAlert, error)); ok {
- return rf(ctx, params, ids)
- }
- if rf, ok := ret.Get(0).(func(context.Context, *services.FilterParams, []string) []*ammodels.GettableAlert); ok {
- r0 = rf(ctx, params, ids)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).([]*ammodels.GettableAlert)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, *services.FilterParams, []string) error); ok {
- r1 = rf(ctx, params, ids)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// GetAlerts provides a mock function with given fields: ctx, params
-func (_m *mockAlertManager) GetAlerts(ctx context.Context, params *services.FilterParams) ([]*ammodels.GettableAlert, error) {
- ret := _m.Called(ctx, params)
-
- var r0 []*ammodels.GettableAlert
- var r1 error
- if rf, ok := ret.Get(0).(func(context.Context, *services.FilterParams) ([]*ammodels.GettableAlert, error)); ok {
- return rf(ctx, params)
- }
- if rf, ok := ret.Get(0).(func(context.Context, *services.FilterParams) []*ammodels.GettableAlert); ok {
- r0 = rf(ctx, params)
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).([]*ammodels.GettableAlert)
- }
- }
-
- if rf, ok := ret.Get(1).(func(context.Context, *services.FilterParams) error); ok {
- r1 = rf(ctx, params)
- } else {
- r1 = ret.Error(1)
- }
-
- return r0, r1
-}
-
-// RequestConfigurationUpdate provides a mock function with given fields:
-func (_m *mockAlertManager) RequestConfigurationUpdate() {
- _m.Called()
-}
-
-// SilenceAlerts provides a mock function with given fields: ctx, alerts
-func (_m *mockAlertManager) SilenceAlerts(ctx context.Context, alerts []*ammodels.GettableAlert) error {
- ret := _m.Called(ctx, alerts)
-
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, []*ammodels.GettableAlert) error); ok {
- r0 = rf(ctx, alerts)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// UnsilenceAlerts provides a mock function with given fields: ctx, alerts
-func (_m *mockAlertManager) UnsilenceAlerts(ctx context.Context, alerts []*ammodels.GettableAlert) error {
- ret := _m.Called(ctx, alerts)
-
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, []*ammodels.GettableAlert) error); ok {
- r0 = rf(ctx, alerts)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
-// newMockAlertManager creates a new instance of mockAlertManager. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func newMockAlertManager(t interface {
- mock.TestingT
- Cleanup(func())
-},
-) *mockAlertManager {
- mock := &mockAlertManager{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/managed/services/management/ia/mock_templates_service_test.go b/managed/services/management/ia/mock_templates_service_test.go
deleted file mode 100644
index fd979a674c..0000000000
--- a/managed/services/management/ia/mock_templates_service_test.go
+++ /dev/null
@@ -1,45 +0,0 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
-
-package ia
-
-import (
- mock "github.com/stretchr/testify/mock"
-
- alerting "github.com/percona/pmm/managed/services/management/alerting"
-)
-
-// mockTemplatesService is an autogenerated mock type for the templatesService type
-type mockTemplatesService struct {
- mock.Mock
-}
-
-// GetTemplates provides a mock function with given fields:
-func (_m *mockTemplatesService) GetTemplates() map[string]alerting.TemplateInfo {
- ret := _m.Called()
-
- var r0 map[string]alerting.TemplateInfo
- if rf, ok := ret.Get(0).(func() map[string]alerting.TemplateInfo); ok {
- r0 = rf()
- } else {
- if ret.Get(0) != nil {
- r0 = ret.Get(0).(map[string]alerting.TemplateInfo)
- }
- }
-
- return r0
-}
-
-// newMockTemplatesService creates a new instance of mockTemplatesService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func newMockTemplatesService(t interface {
- mock.TestingT
- Cleanup(func())
-},
-) *mockTemplatesService {
- mock := &mockTemplatesService{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/managed/services/management/ia/mock_vm_alert_test.go b/managed/services/management/ia/mock_vm_alert_test.go
deleted file mode 100644
index f4d881db5e..0000000000
--- a/managed/services/management/ia/mock_vm_alert_test.go
+++ /dev/null
@@ -1,30 +0,0 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
-
-package ia
-
-import mock "github.com/stretchr/testify/mock"
-
-// mockVmAlert is an autogenerated mock type for the vmAlert type
-type mockVmAlert struct {
- mock.Mock
-}
-
-// RequestConfigurationUpdate provides a mock function with given fields:
-func (_m *mockVmAlert) RequestConfigurationUpdate() {
- _m.Called()
-}
-
-// newMockVmAlert creates a new instance of mockVmAlert. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
-// The first argument is typically a *testing.T value.
-func newMockVmAlert(t interface {
- mock.TestingT
- Cleanup(func())
-},
-) *mockVmAlert {
- mock := &mockVmAlert{}
- mock.Mock.Test(t)
-
- t.Cleanup(func() { mock.AssertExpectations(t) })
-
- return mock
-}
diff --git a/managed/services/management/management.go b/managed/services/management/management.go
index e45bbc22fd..fcf312062c 100644
--- a/managed/services/management/management.go
+++ b/managed/services/management/management.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/mock_agents_registry_test.go b/managed/services/management/mock_agents_registry_test.go
index 0dbb0951da..389a81139a 100644
--- a/managed/services/management/mock_agents_registry_test.go
+++ b/managed/services/management/mock_agents_registry_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package management
diff --git a/managed/services/management/mock_agents_state_updater_test.go b/managed/services/management/mock_agents_state_updater_test.go
index ce3b259251..2115c2a4a8 100644
--- a/managed/services/management/mock_agents_state_updater_test.go
+++ b/managed/services/management/mock_agents_state_updater_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package management
diff --git a/managed/services/management/mock_api_key_provider_test.go b/managed/services/management/mock_api_key_provider_test.go
index 212d9665c4..45ebeb1966 100644
--- a/managed/services/management/mock_api_key_provider_test.go
+++ b/managed/services/management/mock_api_key_provider_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package management
diff --git a/managed/services/management/mock_checks_service_test.go b/managed/services/management/mock_checks_service_test.go
index b8e56ad71e..d28cd5cb01 100644
--- a/managed/services/management/mock_checks_service_test.go
+++ b/managed/services/management/mock_checks_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package management
@@ -202,20 +202,6 @@ func (_m *mockChecksService) StartChecks(checkNames []string) error {
return r0
}
-// ToggleCheckAlert provides a mock function with given fields: ctx, alertID, newStatus
-func (_m *mockChecksService) ToggleCheckAlert(ctx context.Context, alertID string, newStatus bool) error {
- ret := _m.Called(ctx, alertID, newStatus)
-
- var r0 error
- if rf, ok := ret.Get(0).(func(context.Context, string, bool) error); ok {
- r0 = rf(ctx, alertID, newStatus)
- } else {
- r0 = ret.Error(0)
- }
-
- return r0
-}
-
// newMockChecksService creates a new instance of mockChecksService. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations.
// The first argument is typically a *testing.T value.
func newMockChecksService(t interface {
diff --git a/managed/services/management/mock_connection_checker_test.go b/managed/services/management/mock_connection_checker_test.go
index fba5fbe20e..89be9f50d8 100644
--- a/managed/services/management/mock_connection_checker_test.go
+++ b/managed/services/management/mock_connection_checker_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package management
diff --git a/managed/services/management/mock_grafana_client_test.go b/managed/services/management/mock_grafana_client_test.go
index 47f47484f8..d170c74447 100644
--- a/managed/services/management/mock_grafana_client_test.go
+++ b/managed/services/management/mock_grafana_client_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package management
diff --git a/managed/services/management/mock_jobs_service_test.go b/managed/services/management/mock_jobs_service_test.go
index 22e2e7baf3..67acf51ef5 100644
--- a/managed/services/management/mock_jobs_service_test.go
+++ b/managed/services/management/mock_jobs_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package management
diff --git a/managed/services/management/mock_prometheus_service_test.go b/managed/services/management/mock_prometheus_service_test.go
index 2c7ae426f1..974768fb28 100644
--- a/managed/services/management/mock_prometheus_service_test.go
+++ b/managed/services/management/mock_prometheus_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package management
diff --git a/managed/services/management/mock_version_cache_test.go b/managed/services/management/mock_version_cache_test.go
index 55b49d89ed..fd25485e30 100644
--- a/managed/services/management/mock_version_cache_test.go
+++ b/managed/services/management/mock_version_cache_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package management
diff --git a/managed/services/management/mock_victoria_metrics_client_test.go b/managed/services/management/mock_victoria_metrics_client_test.go
index 3a9733f06b..f94d27b297 100644
--- a/managed/services/management/mock_victoria_metrics_client_test.go
+++ b/managed/services/management/mock_victoria_metrics_client_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package management
diff --git a/managed/services/management/mongodb.go b/managed/services/management/mongodb.go
index de7d063415..e016d47aa5 100644
--- a/managed/services/management/mongodb.go
+++ b/managed/services/management/mongodb.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/mysql.go b/managed/services/management/mysql.go
index 5493bbdffb..e67f05eced 100644
--- a/managed/services/management/mysql.go
+++ b/managed/services/management/mysql.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/node.go b/managed/services/management/node.go
index 0c17d5e3ea..f8a43a2220 100644
--- a/managed/services/management/node.go
+++ b/managed/services/management/node.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/node_mgmt.go b/managed/services/management/node_mgmt.go
index 694706b116..cacc35a460 100644
--- a/managed/services/management/node_mgmt.go
+++ b/managed/services/management/node_mgmt.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/node_mgmt_test.go b/managed/services/management/node_mgmt_test.go
index 6cf7582e84..92ca762c90 100644
--- a/managed/services/management/node_mgmt_test.go
+++ b/managed/services/management/node_mgmt_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -35,9 +35,9 @@ import (
"github.com/percona/pmm/api/inventorypb"
nodev1beta1 "github.com/percona/pmm/api/managementpb/node"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
func TestMgmtNodeService(t *testing.T) {
diff --git a/managed/services/management/node_test.go b/managed/services/management/node_test.go
index eeb6ad0a28..8f6bcf9f14 100644
--- a/managed/services/management/node_test.go
+++ b/managed/services/management/node_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -31,9 +31,9 @@ import (
"github.com/percona/pmm/api/inventorypb"
"github.com/percona/pmm/api/managementpb"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
func TestNodeService(t *testing.T) {
diff --git a/managed/services/management/postgresql.go b/managed/services/management/postgresql.go
index dfdf559fa4..536d593b42 100644
--- a/managed/services/management/postgresql.go
+++ b/managed/services/management/postgresql.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/proxysql.go b/managed/services/management/proxysql.go
index 88b883bfff..d356b8b321 100644
--- a/managed/services/management/proxysql.go
+++ b/managed/services/management/proxysql.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/rds.go b/managed/services/management/rds.go
index ce79abf322..a669e2c472 100644
--- a/managed/services/management/rds.go
+++ b/managed/services/management/rds.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -39,11 +39,11 @@ import (
"github.com/percona/pmm/api/managementpb"
"github.com/percona/pmm/managed/models"
"github.com/percona/pmm/managed/services"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
)
const (
- // Maximum time for AWS discover APIs calls
+ // Maximum time for AWS discover APIs calls.
awsDiscoverTimeout = 7 * time.Second
)
@@ -66,7 +66,7 @@ func NewRDSService(db *reform.DB, state agentsStateUpdater, cc connectionChecker
}
var (
- // See https://pkg.go.dev/github.com/aws/aws-sdk-go/service/rds?tab=doc#CreateDBInstanceInput, Engine field
+ // See https://pkg.go.dev/github.com/aws/aws-sdk-go/service/rds?tab=doc#CreateDBInstanceInput, Engine field.
rdsEngines = map[string]managementpb.DiscoverRDSEngine{
"aurora-mysql": managementpb.DiscoverRDSEngine_DISCOVER_RDS_MYSQL, // MySQL 5.7-compatible Aurora
@@ -387,6 +387,7 @@ func (s *RDSService) AddRDS(ctx context.Context, req *managementpb.AddRDSRequest
CustomLabels: req.CustomLabels,
Address: &req.Address,
Port: pointer.ToUint16(uint16(req.Port)),
+ Database: req.Database,
})
if err != nil {
return err
diff --git a/managed/services/management/rds_test.go b/managed/services/management/rds_test.go
index b40fdcaed0..3cac4518e4 100644
--- a/managed/services/management/rds_test.go
+++ b/managed/services/management/rds_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -38,9 +38,9 @@ import (
"github.com/percona/pmm/api/inventorypb"
"github.com/percona/pmm/api/managementpb"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
func TestRDSService(t *testing.T) {
@@ -88,6 +88,7 @@ func TestRDSService(t *testing.T) {
"eu-west-1",
"eu-west-2",
"eu-west-3",
+ "il-central-1",
"me-central-1",
"me-south-1",
"sa-east-1",
diff --git a/managed/services/management/role.go b/managed/services/management/role.go
index c8164c8e52..2448ee88dc 100644
--- a/managed/services/management/role.go
+++ b/managed/services/management/role.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/role_test.go b/managed/services/management/role_test.go
index b23e6270ed..5aeaa57c24 100644
--- a/managed/services/management/role_test.go
+++ b/managed/services/management/role_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -28,9 +28,9 @@ import (
rolev1beta1 "github.com/percona/pmm/api/managementpb/role"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
//nolint:paralleltest
diff --git a/managed/services/management/service.go b/managed/services/management/service.go
index 4d9a49f68a..e659a31375 100644
--- a/managed/services/management/service.go
+++ b/managed/services/management/service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/service_mgmt.go b/managed/services/management/service_mgmt.go
index aefa0dcc63..73f3febf5d 100644
--- a/managed/services/management/service_mgmt.go
+++ b/managed/services/management/service_mgmt.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/management/service_mgmt_test.go b/managed/services/management/service_mgmt_test.go
index 5946195c91..29f783428d 100644
--- a/managed/services/management/service_mgmt_test.go
+++ b/managed/services/management/service_mgmt_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -30,9 +30,9 @@ import (
servicev1beta1 "github.com/percona/pmm/api/managementpb/service"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
func TestMgmtServiceService(t *testing.T) {
diff --git a/managed/services/management/service_test.go b/managed/services/management/service_test.go
index 4aaca4ce96..0c4c535d9d 100644
--- a/managed/services/management/service_test.go
+++ b/managed/services/management/service_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -32,9 +32,9 @@ import (
"github.com/percona/pmm/api/inventorypb"
"github.com/percona/pmm/api/managementpb"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
"github.com/percona/pmm/managed/utils/tests"
+ "github.com/percona/pmm/utils/logger"
)
func TestServiceService(t *testing.T) {
diff --git a/managed/services/minio/client.go b/managed/services/minio/client.go
index 103ac3b19d..037d6c84cb 100644
--- a/managed/services/minio/client.go
+++ b/managed/services/minio/client.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/platform/deps.go b/managed/services/platform/deps.go
index 501299f19a..ce6e4c2f09 100644
--- a/managed/services/platform/deps.go
+++ b/managed/services/platform/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/platform/platform.go b/managed/services/platform/platform.go
index 5af433c5db..4b75510ed9 100644
--- a/managed/services/platform/platform.go
+++ b/managed/services/platform/platform.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/preconditions.go b/managed/services/preconditions.go
index 6f2f40293c..8df82edd78 100644
--- a/managed/services/preconditions.go
+++ b/managed/services/preconditions.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -17,6 +17,7 @@ package services
import (
"github.com/AlekSi/pointer"
+ "github.com/pkg/errors"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"gopkg.in/reform.v1"
@@ -25,7 +26,8 @@ import (
)
// CheckMongoDBBackupPreconditions checks compatibility of different types of scheduled backups and on-demand backups for MongoDB.
-// WARNING: This function valid only when executed as part of transaction with serializable isolation level.
+//
+// WARNING: This function is valid only when executed as part of transaction with serializable isolation level.
func CheckMongoDBBackupPreconditions(q *reform.Querier, mode models.BackupMode, clusterName, serviceID, scheduleID string) error {
filter := models.ScheduledTasksFilter{
Disabled: pointer.ToBool(false),
@@ -87,3 +89,88 @@ func CheckMongoDBBackupPreconditions(q *reform.Querier, mode models.BackupMode,
return nil
}
+
+// CheckArtifactOverlapping checks if there are other artifacts or scheduled tasks pointing to the same location and folder.
+// Placing MySQL and MongoDB artifacts in the same folder is not desirable, while placing MongoDB artifacts of different clusters
+// in the same folder may cause data inconsistency.
+//
+// WARNING: This function is valid only when executed as part of transaction with serializable isolation level.
+func CheckArtifactOverlapping(q *reform.Querier, serviceID, locationID, folder string) error {
+ // TODO This doesn't work for all cases. For example, there may exist more than one storage locations pointing to the same place.
+
+ const (
+ usedByArtifactMsg = "Same location and folder already used for artifact %s of other service: %s"
+ usedByScheduledTaskMsg = "Same location and folder already used for scheduled task %s of other service: %s"
+ )
+
+ service, err := models.FindServiceByID(q, serviceID)
+ if err != nil {
+ return err
+ }
+
+ artifacts, err := models.FindArtifacts(q, models.ArtifactFilters{
+ LocationID: locationID,
+ Folder: &folder,
+ })
+ if err != nil {
+ return err
+ }
+
+ for _, artifact := range artifacts {
+ // We skip artifacts made on services that are no longer exists in PMM. However, in future we can improve this function
+ // by storing required information right in artifact model.
+ if artifact.ServiceID != "" && artifact.ServiceID != serviceID {
+ svc, err := models.FindServiceByID(q, artifact.ServiceID)
+ if err != nil {
+ return err
+ }
+
+ if service.ServiceType == models.MySQLServiceType && svc.ServiceType == models.MySQLServiceType {
+ continue
+ }
+
+ if service.ServiceType == models.MongoDBServiceType && svc.ServiceType == models.MongoDBServiceType {
+ if svc.Cluster != service.Cluster {
+ return errors.Wrapf(ErrLocationFolderPairAlreadyUsed, usedByArtifactMsg, artifact.ID, serviceID)
+ }
+ continue
+ }
+
+ return errors.Wrapf(ErrLocationFolderPairAlreadyUsed, usedByArtifactMsg, artifact.ID, serviceID)
+ }
+ }
+
+ tasks, err := models.FindScheduledTasks(q, models.ScheduledTasksFilter{
+ LocationID: locationID,
+ Folder: &folder,
+ })
+ if err != nil {
+ return err
+ }
+
+ var svcID string
+
+ for _, task := range tasks {
+ svcID, err = task.ServiceID()
+ if err != nil {
+ return err
+ }
+
+ if svcID != serviceID {
+ if service.ServiceType == models.MySQLServiceType && task.Type == models.ScheduledMySQLBackupTask {
+ continue
+ }
+
+ if service.ServiceType == models.MongoDBServiceType && task.Type == models.ScheduledMongoDBBackupTask {
+ if task.Data.MongoDBBackupTask.ClusterName != service.Cluster {
+ return errors.Wrapf(ErrLocationFolderPairAlreadyUsed, usedByScheduledTaskMsg, task.ID, serviceID)
+ }
+ continue
+ }
+
+ return errors.Wrapf(ErrLocationFolderPairAlreadyUsed, usedByScheduledTaskMsg, task.ID, serviceID)
+ }
+ }
+
+ return nil
+}
diff --git a/managed/services/preconditions_test.go b/managed/services/preconditions_test.go
index 323da39472..259b09e4db 100644
--- a/managed/services/preconditions_test.go
+++ b/managed/services/preconditions_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -19,7 +19,10 @@ import (
"context"
"database/sql"
"testing"
+ "time"
+ "github.com/AlekSi/pointer"
+ "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
@@ -144,3 +147,124 @@ func TestCheckMongoDBBackupPreconditions(t *testing.T) {
tests.AssertGRPCError(t, status.New(codes.InvalidArgument, "Incremental backups unsupported for MongoDB"), err)
})
}
+
+func TestCheckArtifactOverlapping(t *testing.T) {
+ sqlDB := testdb.Open(t, models.SkipFixtures, nil)
+ db := reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf))
+ t.Cleanup(func() {
+ require.NoError(t, sqlDB.Close())
+ })
+
+ folder1, folder2 := "folder1", "folder2"
+
+ node, err := models.CreateNode(db.Querier, models.GenericNodeType, &models.CreateNodeParams{
+ NodeName: "test-node",
+ })
+ require.NoError(t, err)
+
+ mongoSvc1, err := models.AddNewService(db.Querier, models.MongoDBServiceType, &models.AddDBMSServiceParams{
+ ServiceName: "mongodb1",
+ NodeID: node.NodeID,
+ Address: pointer.ToString("127.0.0.1"),
+ Port: pointer.ToUint16(60000),
+ Cluster: "cluster1",
+ })
+ require.NoError(t, err)
+
+ mongoSvc2, err := models.AddNewService(db.Querier, models.MongoDBServiceType, &models.AddDBMSServiceParams{
+ ServiceName: "mongodb2",
+ NodeID: node.NodeID,
+ Address: pointer.ToString("127.0.0.1"),
+ Port: pointer.ToUint16(60000),
+ Cluster: "cluster1",
+ })
+ require.NoError(t, err)
+
+ mongoSvc3, err := models.AddNewService(db.Querier, models.MongoDBServiceType, &models.AddDBMSServiceParams{
+ ServiceName: "mongodb3",
+ NodeID: node.NodeID,
+ Address: pointer.ToString("127.0.0.1"),
+ Port: pointer.ToUint16(60000),
+ Cluster: "cluster2",
+ })
+ require.NoError(t, err)
+
+ mysqlSvc1, err := models.AddNewService(db.Querier, models.MySQLServiceType, &models.AddDBMSServiceParams{
+ ServiceName: "mysql1",
+ NodeID: node.NodeID,
+ Address: pointer.ToString("127.0.0.1"),
+ Port: pointer.ToUint16(60000),
+ Cluster: "mysql_cluster_1",
+ })
+ require.NoError(t, err)
+
+ mysqlSvc2, err := models.AddNewService(db.Querier, models.MySQLServiceType, &models.AddDBMSServiceParams{
+ ServiceName: "mysql2",
+ NodeID: node.NodeID,
+ Address: pointer.ToString("127.0.0.1"),
+ Port: pointer.ToUint16(60000),
+ Cluster: "mysql_cluster_2",
+ })
+ require.NoError(t, err)
+
+ location, err := models.CreateBackupLocation(db.Querier, models.CreateBackupLocationParams{
+ Name: "test_location",
+ BackupLocationConfig: models.BackupLocationConfig{
+ FilesystemConfig: &models.FilesystemLocationConfig{
+ Path: "/tmp",
+ },
+ },
+ })
+ require.NoError(t, err)
+
+ _, err = models.CreateScheduledTask(db.Querier, models.CreateScheduledTaskParams{
+ CronExpression: "* * * * *",
+ StartAt: time.Now().Truncate(time.Second).UTC(),
+ Type: models.ScheduledMongoDBBackupTask,
+ Data: &models.ScheduledTaskData{
+ MongoDBBackupTask: &models.MongoBackupTaskData{
+ CommonBackupTaskData: models.CommonBackupTaskData{
+ ServiceID: mongoSvc1.ServiceID,
+ LocationID: location.ID,
+ Name: "test",
+ Description: "test backup task",
+ DataModel: models.LogicalDataModel,
+ Mode: models.Snapshot,
+ Retention: 7,
+ Retries: 3,
+ RetryInterval: 5 * time.Second,
+ ClusterName: "cluster1",
+ Folder: folder1,
+ },
+ },
+ },
+ })
+ require.NoError(t, err)
+
+ _, err = models.CreateArtifact(db.Querier, models.CreateArtifactParams{
+ Name: "test_artifact",
+ Vendor: "mysql",
+ LocationID: location.ID,
+ ServiceID: mysqlSvc1.ServiceID,
+ DataModel: models.LogicalDataModel,
+ Mode: models.Snapshot,
+ Status: models.SuccessBackupStatus,
+ Folder: folder2,
+ })
+ require.NoError(t, err)
+
+ err = CheckArtifactOverlapping(db.Querier, mongoSvc2.ServiceID, location.ID, folder1)
+ assert.NoError(t, err)
+
+ err = CheckArtifactOverlapping(db.Querier, mongoSvc3.ServiceID, location.ID, folder1)
+ assert.ErrorIs(t, err, ErrLocationFolderPairAlreadyUsed)
+
+ err = CheckArtifactOverlapping(db.Querier, mysqlSvc1.ServiceID, location.ID, folder1)
+ assert.ErrorIs(t, err, ErrLocationFolderPairAlreadyUsed)
+
+ err = CheckArtifactOverlapping(db.Querier, mysqlSvc2.ServiceID, location.ID, folder2)
+ assert.NoError(t, err)
+
+ err = CheckArtifactOverlapping(db.Querier, mongoSvc1.ServiceID, location.ID, folder2)
+ assert.ErrorIs(t, err, ErrLocationFolderPairAlreadyUsed)
+}
diff --git a/managed/services/qan/client.go b/managed/services/qan/client.go
index 4b48c8e172..b84f4b87e8 100644
--- a/managed/services/qan/client.go
+++ b/managed/services/qan/client.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -141,6 +141,21 @@ func (c *Client) ExplainFingerprintByQueryID(ctx context.Context, serviceID, que
return res, nil
}
+// SchemaByQueryID returns schema for given queryID and serviceID.
+func (c *Client) SchemaByQueryID(ctx context.Context, serviceID, queryID string) (*qanpb.SchemaByQueryIDReply, error) {
+ qanReq := &qanpb.SchemaByQueryIDRequest{
+ ServiceId: serviceID,
+ QueryId: queryID,
+ }
+ c.l.Debugf("%+v", qanReq)
+ res, err := c.odc.SchemaByQueryID(ctx, qanReq)
+ if err != nil {
+ return nil, err
+ }
+
+ return res, nil
+}
+
// Collect adds labels to the data from pmm-agent and sends it to qan-api.
func (c *Client) Collect(ctx context.Context, metricsBuckets []*agentpb.MetricsBucket) error {
start := time.Now()
diff --git a/managed/services/qan/client_test.go b/managed/services/qan/client_test.go
index bb4bede570..dce12fce95 100644
--- a/managed/services/qan/client_test.go
+++ b/managed/services/qan/client_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -33,8 +33,8 @@ import (
"github.com/percona/pmm/api/inventorypb"
qanpb "github.com/percona/pmm/api/qanpb"
"github.com/percona/pmm/managed/models"
- "github.com/percona/pmm/managed/utils/logger"
"github.com/percona/pmm/managed/utils/testdb"
+ "github.com/percona/pmm/utils/logger"
"github.com/percona/pmm/utils/sqlmetrics"
)
@@ -185,6 +185,7 @@ func TestClient(t *testing.T) {
MQueryTimeSum: 1234,
ServiceId: "/service_id/014647c3-b2f5-44eb-94f4-d943260a968c",
ServiceName: "test-mysql",
+ Cluster: "test-mysql",
ServiceType: "mysql",
NodeId: "/node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d",
NodeName: "test-generic-node",
@@ -254,6 +255,7 @@ func TestClient(t *testing.T) {
NumQueries: 1,
ServiceId: "/service_id/1fce2502-ecc7-46d4-968b-18d7907f2543",
ServiceName: "test-mongodb",
+ Cluster: "test-mongodb",
ServiceType: "mongodb",
NodeId: "/node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d",
NodeName: "test-generic-node",
@@ -352,6 +354,7 @@ func TestClient(t *testing.T) {
MQueryTimeCnt: 1,
MQueryTimeSum: 55,
ServiceName: "test-postgresql",
+ Cluster: "test-postgresql",
ServiceType: "postgresql",
ServiceId: "/service_id/9cffbdd4-3cd2-47f8-a5f9-a749c3d5fee1",
NodeId: "/node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d",
@@ -492,6 +495,7 @@ func TestClientPerformance(t *testing.T) {
expectedBuckets[i] = &qanpb.MetricsBucket{
Queryid: fmt.Sprintf("bucket %d", i),
ServiceName: "test-mysql",
+ Cluster: "test-mysql",
NodeId: "pmm-server",
NodeName: "pmm-server",
NodeType: "generic",
diff --git a/managed/services/qan/deps.go b/managed/services/qan/deps.go
index f745e18e53..77ce35a6e6 100644
--- a/managed/services/qan/deps.go
+++ b/managed/services/qan/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/qan/mock_qan_collector_client_test.go b/managed/services/qan/mock_qan_collector_client_test.go
index d865ccac66..ba851fb0c2 100644
--- a/managed/services/qan/mock_qan_collector_client_test.go
+++ b/managed/services/qan/mock_qan_collector_client_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package qan
diff --git a/managed/services/scheduler/deps.go b/managed/services/scheduler/deps.go
index 0820f524b5..e0faed3bbf 100644
--- a/managed/services/scheduler/deps.go
+++ b/managed/services/scheduler/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/scheduler/mock_backup_service_test.go b/managed/services/scheduler/mock_backup_service_test.go
index ca8449ad96..3973ae0e3e 100644
--- a/managed/services/scheduler/mock_backup_service_test.go
+++ b/managed/services/scheduler/mock_backup_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package scheduler
diff --git a/managed/services/scheduler/scheduler.go b/managed/services/scheduler/scheduler.go
index 40b3d854c3..bce97c3832 100644
--- a/managed/services/scheduler/scheduler.go
+++ b/managed/services/scheduler/scheduler.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -87,7 +87,7 @@ func (s *Service) Add(task Task, params AddParams) (*models.ScheduledTask, error
// This transaction is valid only with serializable isolation level. On lower isolation levels it can produce anomalies.
errTx := s.db.InTransactionContext(s.db.Querier.Context(), &sql.TxOptions{Isolation: sql.LevelSerializable}, func(tx *reform.TX) error {
var err error
- if err = checkPreconditions(tx.Querier, task.Data(), !params.Disabled, ""); err != nil {
+ if err = checkAddPreconditions(tx.Querier, task.Data(), !params.Disabled, ""); err != nil {
return err
}
scheduledTask, err = models.CreateScheduledTask(tx.Querier, models.CreateScheduledTaskParams{
@@ -158,7 +158,7 @@ func (s *Service) Remove(id string) error {
// Update changes scheduled task in DB and re-add it to scheduler.
func (s *Service) Update(id string, params models.ChangeScheduledTaskParams) error {
return s.db.InTransactionContext(s.db.Querier.Context(), &sql.TxOptions{Isolation: sql.LevelSerializable}, func(tx *reform.TX) error {
- if err := checkPreconditions(tx.Querier, params.Data, !pointer.GetBool(params.Disable), id); err != nil {
+ if err := checkUpdatePreconditions(tx.Querier, params.Data, !pointer.GetBool(params.Disable), id); err != nil {
return err
}
@@ -352,7 +352,29 @@ func (s *Service) convertDBTask(dbTask *models.ScheduledTask) (Task, error) { //
return task, nil
}
-func checkPreconditions(q *reform.Querier, data *models.ScheduledTaskData, enabled bool, scheduledTaskID string) error {
+func checkAddPreconditions(q *reform.Querier, data *models.ScheduledTaskData, enabled bool, scheduledTaskID string) error {
+ switch {
+ case data.MySQLBackupTask != nil:
+ if err := services.CheckArtifactOverlapping(q, data.MySQLBackupTask.ServiceID, data.MySQLBackupTask.LocationID, data.MySQLBackupTask.Folder); err != nil {
+ return err
+ }
+ case data.MongoDBBackupTask != nil:
+ if err := services.CheckArtifactOverlapping(q, data.MongoDBBackupTask.ServiceID, data.MongoDBBackupTask.LocationID, data.MongoDBBackupTask.Folder); err != nil {
+ return err
+ }
+ if enabled {
+ return services.CheckMongoDBBackupPreconditions(
+ q,
+ data.MongoDBBackupTask.Mode,
+ data.MongoDBBackupTask.ClusterName,
+ data.MongoDBBackupTask.ServiceID,
+ scheduledTaskID)
+ }
+ }
+ return nil
+}
+
+func checkUpdatePreconditions(q *reform.Querier, data *models.ScheduledTaskData, enabled bool, scheduledTaskID string) error {
switch {
case data.MySQLBackupTask != nil:
case data.MongoDBBackupTask != nil:
diff --git a/managed/services/scheduler/scheduler_test.go b/managed/services/scheduler/scheduler_test.go
index ae011f6525..0967c34b77 100644
--- a/managed/services/scheduler/scheduler_test.go
+++ b/managed/services/scheduler/scheduler_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -20,6 +20,7 @@ import (
"testing"
"time"
+ "github.com/AlekSi/pointer"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/grpc/codes"
@@ -33,30 +34,58 @@ import (
)
func TestService(t *testing.T) {
- setup := func(t *testing.T, ctx context.Context) *Service {
+ setup := func(t *testing.T, ctx context.Context, serviceType models.ServiceType, serviceName string) (*Service, *models.Service, *models.BackupLocation) {
t.Helper()
sqlDB := testdb.Open(t, models.SkipFixtures, nil)
+ t.Cleanup(func() {
+ require.NoError(t, sqlDB.Close())
+ })
+
db := reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf))
+
+ node, err := models.CreateNode(db.Querier, models.GenericNodeType, &models.CreateNodeParams{
+ NodeName: "test-node-" + t.Name(),
+ })
+ require.NoError(t, err)
+
+ service, err := models.AddNewService(db.Querier, serviceType, &models.AddDBMSServiceParams{
+ ServiceName: serviceName,
+ NodeID: node.NodeID,
+ Address: pointer.ToString("127.0.0.1"),
+ Port: pointer.ToUint16(60000),
+ })
+ require.NoError(t, err)
+
+ location, err := models.CreateBackupLocation(db.Querier, models.CreateBackupLocationParams{
+ Name: "test_location",
+ BackupLocationConfig: models.BackupLocationConfig{
+ FilesystemConfig: &models.FilesystemLocationConfig{
+ Path: "/tmp",
+ },
+ },
+ })
+ require.NoError(t, err)
+
backupService := &mockBackupService{}
- svc := New(db, backupService)
+ schedulerSvc := New(db, backupService)
- go svc.Run(ctx)
- for !svc.scheduler.IsRunning() {
+ go schedulerSvc.Run(ctx)
+ for !schedulerSvc.scheduler.IsRunning() {
// Wait a while, so scheduler is running
time.Sleep(time.Millisecond * 10)
}
- return svc
+ return schedulerSvc, service, location
}
t.Run("invalid cron expression", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
- svc := setup(t, ctx)
+ scheduler, service, location := setup(t, ctx, models.MongoDBServiceType, "mongo_service")
task, err := NewMongoDBBackupTask(&BackupTaskParams{
- ServiceID: "/service/test",
- LocationID: "/location/test",
+ ServiceID: service.ServiceID,
+ LocationID: location.ID,
Name: "test",
Description: "test backup task",
DataModel: models.LogicalDataModel,
@@ -69,7 +98,7 @@ func TestService(t *testing.T) {
cronExpr := "invalid * cron * expression"
startAt := time.Now().Truncate(time.Second).UTC()
- _, err = svc.Add(task, AddParams{
+ _, err = scheduler.Add(task, AddParams{
CronExpression: cronExpr,
StartAt: startAt,
})
@@ -79,11 +108,11 @@ func TestService(t *testing.T) {
t.Run("normal", func(t *testing.T) {
ctx, cancel := context.WithCancel(context.Background())
defer cancel()
- svc := setup(t, ctx)
+ scheduler, service, location := setup(t, ctx, models.MongoDBServiceType, "mongo_service")
task, err := NewMongoDBBackupTask(&BackupTaskParams{
- ServiceID: "/service/test",
- LocationID: "/location/test",
+ ServiceID: service.ServiceID,
+ LocationID: location.ID,
Name: "test",
Description: "test backup task",
DataModel: models.LogicalDataModel,
@@ -96,25 +125,25 @@ func TestService(t *testing.T) {
cronExpr := "* * * * *"
startAt := time.Now().Truncate(time.Second).UTC()
- dbTask, err := svc.Add(task, AddParams{
+ dbTask, err := scheduler.Add(task, AddParams{
CronExpression: cronExpr,
StartAt: startAt,
})
require.NoError(t, err)
- assert.Len(t, svc.scheduler.Jobs(), 1)
+ assert.Len(t, scheduler.scheduler.Jobs(), 1)
- findJob, err := models.FindScheduledTaskByID(svc.db.Querier, dbTask.ID)
+ findJob, err := models.FindScheduledTaskByID(scheduler.db.Querier, dbTask.ID)
require.NoError(t, err)
assert.Equal(t, startAt, dbTask.StartAt)
assert.Equal(t, cronExpr, findJob.CronExpression)
assert.Truef(t, dbTask.NextRun.After(startAt), "next run %s is before startAt %s", dbTask.NextRun, startAt)
- err = svc.Remove(dbTask.ID)
+ err = scheduler.Remove(dbTask.ID)
require.NoError(t, err)
- assert.Len(t, svc.scheduler.Jobs(), 0)
+ assert.Len(t, scheduler.scheduler.Jobs(), 0)
- _, err = models.FindScheduledTaskByID(svc.db.Querier, dbTask.ID)
+ _, err = models.FindScheduledTaskByID(scheduler.db.Querier, dbTask.ID)
assert.ErrorIs(t, err, models.ErrNotFound)
})
}
diff --git a/managed/services/scheduler/task.go b/managed/services/scheduler/task.go
index c277623822..0a26b869ec 100644
--- a/managed/services/scheduler/task.go
+++ b/managed/services/scheduler/task.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/scheduler/task_test.go b/managed/services/scheduler/task_test.go
index a83e80bcb5..c08b65025f 100644
--- a/managed/services/scheduler/task_test.go
+++ b/managed/services/scheduler/task_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/server/aws_instance_checker.go b/managed/services/server/aws_instance_checker.go
index a233eb4ea3..7b95abbaf1 100644
--- a/managed/services/server/aws_instance_checker.go
+++ b/managed/services/server/aws_instance_checker.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/server/aws_instance_checker_test.go b/managed/services/server/aws_instance_checker_test.go
index a82df34a22..86888b9028 100644
--- a/managed/services/server/aws_instance_checker_test.go
+++ b/managed/services/server/aws_instance_checker_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/server/deps.go b/managed/services/server/deps.go
index b3cd8cf385..132c54c673 100644
--- a/managed/services/server/deps.go
+++ b/managed/services/server/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/server/mock_agents_state_updater_test.go b/managed/services/server/mock_agents_state_updater_test.go
index f898983cf7..c9265cea29 100644
--- a/managed/services/server/mock_agents_state_updater_test.go
+++ b/managed/services/server/mock_agents_state_updater_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package server
diff --git a/managed/services/server/mock_alertmanager_service_test.go b/managed/services/server/mock_alertmanager_service_test.go
index dccb8a57ac..2f572efeab 100644
--- a/managed/services/server/mock_alertmanager_service_test.go
+++ b/managed/services/server/mock_alertmanager_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package server
diff --git a/managed/services/server/mock_checks_service_test.go b/managed/services/server/mock_checks_service_test.go
index 495e30987d..74907d7100 100644
--- a/managed/services/server/mock_checks_service_test.go
+++ b/managed/services/server/mock_checks_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package server
diff --git a/managed/services/server/mock_grafana_client_test.go b/managed/services/server/mock_grafana_client_test.go
index 2c817be76d..d3d55f991d 100644
--- a/managed/services/server/mock_grafana_client_test.go
+++ b/managed/services/server/mock_grafana_client_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package server
diff --git a/managed/services/server/mock_prometheus_service_test.go b/managed/services/server/mock_prometheus_service_test.go
index e4282703be..10105c39a9 100644
--- a/managed/services/server/mock_prometheus_service_test.go
+++ b/managed/services/server/mock_prometheus_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package server
diff --git a/managed/services/server/mock_supervisord_service_test.go b/managed/services/server/mock_supervisord_service_test.go
index 8263ddf2a6..618efe3e39 100644
--- a/managed/services/server/mock_supervisord_service_test.go
+++ b/managed/services/server/mock_supervisord_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package server
diff --git a/managed/services/server/mock_telemetry_service_test.go b/managed/services/server/mock_telemetry_service_test.go
index d68973dd3f..328a321100 100644
--- a/managed/services/server/mock_telemetry_service_test.go
+++ b/managed/services/server/mock_telemetry_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package server
diff --git a/managed/services/server/mock_templates_service_test.go b/managed/services/server/mock_templates_service_test.go
index ae6465fa8a..7228594d53 100644
--- a/managed/services/server/mock_templates_service_test.go
+++ b/managed/services/server/mock_templates_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package server
diff --git a/managed/services/server/mock_vm_alert_external_rules_test.go b/managed/services/server/mock_vm_alert_external_rules_test.go
index 3c08560357..a855ad4006 100644
--- a/managed/services/server/mock_vm_alert_external_rules_test.go
+++ b/managed/services/server/mock_vm_alert_external_rules_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package server
diff --git a/managed/services/server/server.go b/managed/services/server/server.go
index ad9bf98f51..e7e29c2afb 100644
--- a/managed/services/server/server.go
+++ b/managed/services/server/server.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -487,6 +487,7 @@ func (s *Server) validateChangeSettingsRequest(ctx context.Context, req *serverp
if req.PmmPublicAddress != "" && req.RemovePmmPublicAddress {
return status.Error(codes.InvalidArgument, "Both pmm_public_address and remove_pmm_public_address are present.")
}
+
if req.SshKey != "" {
if err := s.validateSSHKey(ctx, req.SshKey); err != nil {
return err
diff --git a/managed/services/server/server_test.go b/managed/services/server/server_test.go
index 3d49ce3d2d..f9f6ddbe99 100644
--- a/managed/services/server/server_test.go
+++ b/managed/services/server/server_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/supervisord/deps.go b/managed/services/supervisord/deps.go
new file mode 100644
index 0000000000..9de477c334
--- /dev/null
+++ b/managed/services/supervisord/deps.go
@@ -0,0 +1,25 @@
+// Copyright (C) 2023 Percona LLC
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU Affero General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU Affero General Public License for more details.
+//
+// You should have received a copy of the GNU Affero General Public License
+// along with this program. If not, see .
+
+package supervisord
+
+import "net/url"
+
+// victoriaMetricsParams is a subset of methods of models.VMParams used by this package.
+// We use it instead of real type to avoid dependency cycle.
+type victoriaMetricsParams interface {
+ ExternalVM() bool
+ URLFor(path string) (*url.URL, error)
+}
diff --git a/managed/services/supervisord/devcontainer_test.go b/managed/services/supervisord/devcontainer_test.go
index e3f0992f0a..6a545e7ec9 100644
--- a/managed/services/supervisord/devcontainer_test.go
+++ b/managed/services/supervisord/devcontainer_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -112,7 +112,9 @@ func TestDevContainer(t *testing.T) {
t.Run("UpdateConfiguration", func(t *testing.T) {
// logrus.SetLevel(logrus.DebugLevel)
checker := NewPMMUpdateChecker(logrus.WithField("test", t.Name()))
- vmParams := &models.VictoriaMetricsParams{}
+ vmParams, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL)
+ require.NoError(t, err)
+
s := New("/etc/supervisord.d", checker, vmParams, models.PGParams{}, gRPCMessageMaxSize)
require.NotEmpty(t, s.supervisorctlPath)
diff --git a/managed/services/supervisord/logs.go b/managed/services/supervisord/logs.go
index f347b3b986..0445ab97cd 100644
--- a/managed/services/supervisord/logs.go
+++ b/managed/services/supervisord/logs.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -37,8 +37,8 @@ import (
"golang.org/x/sys/unix"
"gopkg.in/yaml.v3"
- "github.com/percona/pmm/managed/utils/logger"
pprofUtils "github.com/percona/pmm/managed/utils/pprof"
+ "github.com/percona/pmm/utils/logger"
"github.com/percona/pmm/utils/pdeathsig"
)
@@ -59,14 +59,16 @@ type fileContent struct {
type Logs struct {
pmmVersion string
pmmUpdateChecker *PMMUpdateChecker
+ vmParams victoriaMetricsParams
}
// NewLogs creates a new Logs service.
// The number of last log lines to read is n.
-func NewLogs(pmmVersion string, pmmUpdateChecker *PMMUpdateChecker) *Logs {
+func NewLogs(pmmVersion string, pmmUpdateChecker *PMMUpdateChecker, vmParams victoriaMetricsParams) *Logs {
return &Logs{
pmmVersion: pmmVersion,
pmmUpdateChecker: pmmUpdateChecker,
+ vmParams: vmParams,
}
}
@@ -215,7 +217,7 @@ func (l *Logs) files(ctx context.Context, pprofConfig *PprofConfig) []fileConten
})
// add VictoriaMetrics targets
- b, err = readURL(ctx, "http://127.0.0.1:9090/prometheus/api/v1/targets")
+ b, err = l.victoriaMetricsTargets(ctx)
files = append(files, fileContent{
Name: "victoriametrics_targets.json",
Data: b,
@@ -280,6 +282,14 @@ func (l *Logs) files(ctx context.Context, pprofConfig *PprofConfig) []fileConten
return files
}
+func (l *Logs) victoriaMetricsTargets(ctx context.Context) ([]byte, error) {
+ targetsURL, err := l.vmParams.URLFor("api/v1/targets")
+ if err != nil {
+ return nil, err
+ }
+ return readURL(ctx, targetsURL.String())
+}
+
// readLog reads last lines (up to given number of lines and bytes) from given file,
// and returns them together with modification time.
func readLog(name string, maxLines int, maxBytes int64) ([]byte, time.Time, error) {
diff --git a/managed/services/supervisord/logs_test.go b/managed/services/supervisord/logs_test.go
index 18742b8cee..ebdf0f78f6 100644
--- a/managed/services/supervisord/logs_test.go
+++ b/managed/services/supervisord/logs_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -31,7 +31,8 @@ import (
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/managed/models"
+ "github.com/percona/pmm/utils/logger"
)
var commonExpectedFiles = []string{
@@ -55,7 +56,6 @@ var commonExpectedFiles = []string{
"postgresql14.log",
"qan-api2.ini",
"qan-api2.log",
- "supervisorctl_status.log",
"supervisord.conf",
"supervisord.log",
"victoriametrics-promscrape.yml",
@@ -148,7 +148,9 @@ func TestAddAdminSummary(t *testing.T) {
func TestFiles(t *testing.T) {
checker := NewPMMUpdateChecker(logrus.WithField("test", t.Name()))
- l := NewLogs("2.4.5", checker)
+ params, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL)
+ require.NoError(t, err)
+ l := NewLogs("2.4.5", checker, params)
ctx := logger.Set(context.Background(), t.Name())
files := l.files(ctx, nil)
@@ -173,6 +175,11 @@ func TestFiles(t *testing.T) {
continue
}
+ if f.Name == "supervisorctl_status.log" {
+ // FIXME: this fails following the transition to EL9
+ continue
+ }
+
assert.NoError(t, f.Err, "name = %q", f.Name)
actual = append(actual, f.Name)
@@ -186,7 +193,9 @@ func TestZip(t *testing.T) {
t.Skip("FIXME")
checker := NewPMMUpdateChecker(logrus.WithField("test", t.Name()))
- l := NewLogs("2.4.5", checker)
+ params, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL)
+ require.NoError(t, err)
+ l := NewLogs("2.4.5", checker, params)
ctx := logger.Set(context.Background(), t.Name())
var buf bytes.Buffer
diff --git a/managed/services/supervisord/maintail.go b/managed/services/supervisord/maintail.go
index 1d61e30586..1dd1f62e4c 100644
--- a/managed/services/supervisord/maintail.go
+++ b/managed/services/supervisord/maintail.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/supervisord/maintail_test.go b/managed/services/supervisord/maintail_test.go
index 94603da72d..2e108a66f6 100644
--- a/managed/services/supervisord/maintail_test.go
+++ b/managed/services/supervisord/maintail_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/supervisord/pmm_config.go b/managed/services/supervisord/pmm_config.go
index 602b9a5546..fbe7f2b51f 100644
--- a/managed/services/supervisord/pmm_config.go
+++ b/managed/services/supervisord/pmm_config.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -166,7 +166,6 @@ priority = 14
command =
/usr/sbin/pmm-managed
--victoriametrics-config=/etc/victoriametrics-promscrape.yml
- --victoriametrics-url=http://127.0.0.1:9090/prometheus
--supervisord-config-dir=/etc/supervisord.d
autorestart = true
autostart = true
diff --git a/managed/services/supervisord/pmm_update_checker.go b/managed/services/supervisord/pmm_update_checker.go
index aa06b04048..fe062da7fe 100644
--- a/managed/services/supervisord/pmm_update_checker.go
+++ b/managed/services/supervisord/pmm_update_checker.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/supervisord/pprof_config.go b/managed/services/supervisord/pprof_config.go
index f4cc63ed62..52ab238389 100644
--- a/managed/services/supervisord/pprof_config.go
+++ b/managed/services/supervisord/pprof_config.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/supervisord/supervisord.go b/managed/services/supervisord/supervisord.go
index 0484e263b0..34907a8547 100644
--- a/managed/services/supervisord/supervisord.go
+++ b/managed/services/supervisord/supervisord.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -76,7 +76,7 @@ type sub struct {
eventTypes []eventType
}
-// values from supervisord configuration
+// values from supervisord configuration.
const (
pmmUpdatePerformProgram = "pmm-update-perform"
pmmUpdatePerformLog = "/srv/logs/pmm-update-perform.log"
@@ -394,20 +394,10 @@ func (s *Service) UpdateLog(offset uint32) ([]string, uint32, error) {
// reload asks supervisord to reload configuration.
func (s *Service) reload(name string) error {
- // See https://github.com/Supervisor/supervisor/issues/1264 for explanation
- // why we do reread + stop/remove/add.
-
if _, err := s.supervisorctl("reread"); err != nil {
s.l.Warn(err)
}
- if _, err := s.supervisorctl("stop", name); err != nil {
- s.l.Warn(err)
- }
- if _, err := s.supervisorctl("remove", name); err != nil {
- s.l.Warn(err)
- }
-
- _, err := s.supervisorctl("add", name)
+ _, err := s.supervisorctl("update", name)
return err
}
@@ -433,7 +423,10 @@ func (s *Service) marshalConfig(tmpl *template.Template, settings *models.Settin
"DataRetentionDays": int(settings.DataRetention.Hours() / 24),
"VMAlertFlags": s.vmParams.VMAlertFlags,
"VMDBCacheDisable": !settings.VictoriaMetrics.CacheEnabled,
+ "VMURL": s.vmParams.URL(),
+ "ExternalVM": s.vmParams.ExternalVM(),
"PerconaTestDbaas": settings.DBaaS.Enabled,
+ "InterfaceToBind": envvars.GetInterfaceToBind(),
"ClickhouseAddr": clickhouseAddr,
"ClickhouseDataSourceAddr": clickhouseDataSourceAddr,
"ClickhouseDatabase": clickhouseDatabase,
@@ -445,6 +438,19 @@ func (s *Service) marshalConfig(tmpl *template.Template, settings *models.Settin
s.addPostgresParams(templateParams)
+ templateParams["PMMServerHost"] = ""
+ if settings.PMMPublicAddress != "" {
+ publicURL, err := url.Parse(settings.PMMPublicAddress)
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to parse PMM public address.")
+ }
+ if publicURL.Host == "" {
+ if publicURL, err = url.Parse(fmt.Sprintf("https://%s", settings.PMMPublicAddress)); err != nil {
+ return nil, errors.Wrap(err, "failed to parse PMM public address.")
+ }
+ }
+ templateParams["PMMServerHost"] = publicURL.Host
+ }
if ssoDetails != nil {
u, err := url.Parse(ssoDetails.IssuerURL)
if err != nil {
@@ -601,8 +607,6 @@ func (s *Service) RestartSupervisedService(serviceName string) error {
return err
}
-var interfaceToBind = envvars.GetInterfaceToBind()
-
//nolint:lll
var templates = template.Must(template.New("").Option("missingkey=error").Parse(`
{{define "dbaas-controller"}}
@@ -639,6 +643,7 @@ redirect_stderr = true
{{end}}
{{define "victoriametrics"}}
+{{- if not .ExternalVM }}
[program:victoriametrics]
priority = 7
command =
@@ -646,7 +651,7 @@ command =
--promscrape.config=/etc/victoriametrics-promscrape.yml
--retentionPeriod={{ .DataRetentionDays }}d
--storageDataPath=/srv/victoriametrics/data
- --httpListenAddr=` + interfaceToBind + `:9090
+ --httpListenAddr={{ .InterfaceToBind }}:9090
--search.disableCache={{ .VMDBCacheDisable }}
--search.maxQueryLen=1MB
--search.latencyOffset=5s
@@ -671,6 +676,7 @@ stdout_logfile = /srv/logs/victoriametrics.log
stdout_logfile_maxbytes = 10MB
stdout_logfile_backups = 3
redirect_stderr = true
+{{end -}}
{{end}}
{{define "vmalert"}}
@@ -681,13 +687,13 @@ command =
--notifier.url="{{ .AlertmanagerURL }}"
--notifier.basicAuth.password='{{ .AlertManagerPassword }}'
--notifier.basicAuth.username="{{ .AlertManagerUser }}"
- --external.url=http://localhost:9090/prometheus
- --datasource.url=http://127.0.0.1:9090/prometheus
- --remoteRead.url=http://127.0.0.1:9090/prometheus
+ --external.url={{ .VMURL }}
+ --datasource.url={{ .VMURL }}
+ --remoteRead.url={{ .VMURL }}
--remoteRead.ignoreRestoreErrors=false
- --remoteWrite.url=http://127.0.0.1:9090/prometheus
+ --remoteWrite.url={{ .VMURL }}
--rule=/srv/prometheus/rules/*.yml
- --httpListenAddr=` + interfaceToBind + `:8880
+ --httpListenAddr={{ .InterfaceToBind }}:8880
{{- range $index, $param := .VMAlertFlags }}
{{ $param }}
{{- end }}
@@ -709,9 +715,9 @@ redirect_stderr = true
priority = 9
command =
/usr/sbin/vmproxy
- --target-url=http://127.0.0.1:9090/
+ --target-url={{ .VMURL }}
--listen-port=8430
- --listen-address=` + interfaceToBind + `
+ --listen-address={{ .InterfaceToBind }}
--header-name=X-Proxy-Filter
user = pmm
autorestart = true
@@ -735,7 +741,7 @@ command =
--storage.path=/srv/alertmanager/data
--data.retention={{ .DataRetentionHours }}h
--web.external-url=http://localhost:9093/alertmanager/
- --web.listen-address=` + interfaceToBind + `:9093
+ --web.listen-address={{ .InterfaceToBind }}:9093
--cluster.listen-address=""
user = pmm
autorestart = true
@@ -778,17 +784,13 @@ redirect_stderr = true
[program:grafana]
priority = 3
command =
- /usr/sbin/grafana-server
+ /usr/sbin/grafana server
--homepath=/usr/share/grafana
--config=/etc/grafana/grafana.ini
- cfg:default.paths.data=/srv/grafana
- cfg:default.paths.plugins=/srv/grafana/plugins
- cfg:default.paths.logs=/srv/logs
- cfg:default.log.mode=console
- cfg:default.log.console.format=console
- cfg:default.server.root_url="https://%%(domain)s/graph"
+ {{- if .PMMServerHost}}
+ cfg:default.server.domain="{{ .PMMServerHost }}"
+ {{- end}}
{{- if .PerconaSSODetails}}
- cfg:default.server.domain="{{ .PMMServerAddress }}"
cfg:default.auth.generic_oauth.enabled=true
cfg:default.auth.generic_oauth.name="Percona Account"
cfg:default.auth.generic_oauth.client_id="{{ .PerconaSSODetails.GrafanaClientID }}"
@@ -798,6 +800,7 @@ command =
cfg:default.auth.generic_oauth.api_url="{{ .PerconaSSODetails.IssuerURL }}/userinfo"
cfg:default.auth.generic_oauth.role_attribute_path="(contains(portal_admin_orgs[*], '{{ .PerconaSSODetails.OrganizationID }}') || contains(pmm_demo_ids[*], '{{ .PMMServerID }}')) && 'Admin' || 'Viewer'"
cfg:default.auth.generic_oauth.use_pkce="true"
+ cfg:default.auth.oauth_allow_insecure_email_lookup="true"
{{- end}}
environment =
PERCONA_TEST_POSTGRES_ADDR="{{ .PostgresAddr }}",
diff --git a/managed/services/supervisord/supervisord_test.go b/managed/services/supervisord/supervisord_test.go
index ed6e515ff5..6676406f39 100644
--- a/managed/services/supervisord/supervisord_test.go
+++ b/managed/services/supervisord/supervisord_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -36,7 +36,8 @@ func TestConfig(t *testing.T) {
pmmUpdateCheck := NewPMMUpdateChecker(logrus.WithField("component", "supervisord/pmm-update-checker_logs"))
configDir := filepath.Join("..", "..", "testdata", "supervisord.d")
- vmParams := &models.VictoriaMetricsParams{}
+ vmParams, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL)
+ require.NoError(t, err)
s := New(configDir, pmmUpdateCheck, vmParams, models.PGParams{}, gRPCMessageMaxSize)
settings := &models.Settings{
DataRetention: 30 * 24 * time.Hour,
@@ -68,7 +69,8 @@ func TestDBaaSController(t *testing.T) {
pmmUpdateCheck := NewPMMUpdateChecker(logrus.WithField("component", "supervisord/pmm-update-checker_logs"))
configDir := filepath.Join("..", "..", "testdata", "supervisord.d")
- vmParams := &models.VictoriaMetricsParams{}
+ vmParams, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL)
+ require.NoError(t, err)
s := New(configDir, pmmUpdateCheck, vmParams, models.PGParams{}, gRPCMessageMaxSize)
var tp *template.Template
diff --git a/managed/services/telemetry/config.go b/managed/services/telemetry/config.go
index 813d0fa437..40372b297f 100644
--- a/managed/services/telemetry/config.go
+++ b/managed/services/telemetry/config.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/telemetry/config_test.go b/managed/services/telemetry/config_test.go
index 33868fbf45..5d497688d0 100644
--- a/managed/services/telemetry/config_test.go
+++ b/managed/services/telemetry/config_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/telemetry/datasource_grafana_sqlitedb.go b/managed/services/telemetry/datasource_grafana_sqlitedb.go
index dfa6606a3b..689a3decfd 100644
--- a/managed/services/telemetry/datasource_grafana_sqlitedb.go
+++ b/managed/services/telemetry/datasource_grafana_sqlitedb.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/telemetry/datasource_grafana_sqlitedb_test.go b/managed/services/telemetry/datasource_grafana_sqlitedb_test.go
index 8edadf5ec8..4877c9263d 100644
--- a/managed/services/telemetry/datasource_grafana_sqlitedb_test.go
+++ b/managed/services/telemetry/datasource_grafana_sqlitedb_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/telemetry/datasource_pmmdb_select.go b/managed/services/telemetry/datasource_pmmdb_select.go
index 6e2d03c040..08e6485e36 100644
--- a/managed/services/telemetry/datasource_pmmdb_select.go
+++ b/managed/services/telemetry/datasource_pmmdb_select.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -33,7 +33,7 @@ type dsPmmDBSelect struct {
db *sql.DB
}
-// check interfaces
+// check interfaces.
var (
_ DataSource = (*dsPmmDBSelect)(nil)
)
diff --git a/managed/services/telemetry/datasource_qandb_select.go b/managed/services/telemetry/datasource_qandb_select.go
index d53a122d86..3f80053282 100644
--- a/managed/services/telemetry/datasource_qandb_select.go
+++ b/managed/services/telemetry/datasource_qandb_select.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -31,7 +31,7 @@ type dsQanDBSelect struct {
db *sql.DB
}
-// check interfaces
+// check interfaces.
var (
_ DataSource = (*dsQanDBSelect)(nil)
)
diff --git a/managed/services/telemetry/datasource_victoria_metrics.go b/managed/services/telemetry/datasource_victoria_metrics.go
index 7b3365f31c..359032aa5c 100644
--- a/managed/services/telemetry/datasource_victoria_metrics.go
+++ b/managed/services/telemetry/datasource_victoria_metrics.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -33,7 +33,7 @@ type dataSourceVictoriaMetrics struct {
vm v1.API
}
-// check interfaces
+// check interfaces.
var (
_ DataSource = (*dataSourceVictoriaMetrics)(nil)
)
diff --git a/managed/services/telemetry/datasources.go b/managed/services/telemetry/datasources.go
index 79276d8aac..01f5e75996 100644
--- a/managed/services/telemetry/datasources.go
+++ b/managed/services/telemetry/datasources.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -35,7 +35,7 @@ type dataSourceRegistry struct {
dataSources map[DataSourceName]DataSource
}
-// NewDataSourceRegistry makes new data source registry
+// NewDataSourceRegistry makes new data source registry.
func NewDataSourceRegistry(config ServiceConfig, l *logrus.Entry) (DataSourceLocator, error) { //nolint:ireturn
pmmDB, err := NewDsPmmDBSelect(*config.DataSources.PmmDBSelect, l)
if err != nil {
diff --git a/managed/services/telemetry/deps.go b/managed/services/telemetry/deps.go
index 148bd529a7..e2f47d9100 100644
--- a/managed/services/telemetry/deps.go
+++ b/managed/services/telemetry/deps.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -29,12 +29,12 @@ import (
//go:generate ../../../bin/mockery --name=DataSourceLocator --case=snake --inpackage --testonly
//go:generate ../../../bin/mockery --name=DataSource --case=snake --inpackage --testonly
-// distributionUtilService service to get info about OS on which pmm server is running
+// distributionUtilService service to get info about OS on which pmm server is running.
type distributionUtilService interface {
getDistributionMethodAndOS() (serverpb.DistributionMethod, pmmv1.DistributionMethod, string)
}
-// sender is interface which defines method for client which sends report with metrics
+// sender is interface which defines method for client which sends report with metrics.
type sender interface {
SendTelemetry(ctx context.Context, report *reporter.ReportRequest) error
}
diff --git a/managed/services/telemetry/distribution_util.go b/managed/services/telemetry/distribution_util.go
index 28213dfd3b..7c27be9d3e 100644
--- a/managed/services/telemetry/distribution_util.go
+++ b/managed/services/telemetry/distribution_util.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/telemetry/distribution_util_test.go b/managed/services/telemetry/distribution_util_test.go
index 59c62bb5c9..cfd1ac5ae8 100644
--- a/managed/services/telemetry/distribution_util_test.go
+++ b/managed/services/telemetry/distribution_util_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/telemetry/mock_data_source_locator_test.go b/managed/services/telemetry/mock_data_source_locator_test.go
index 93ec35e84b..29b11a5efc 100644
--- a/managed/services/telemetry/mock_data_source_locator_test.go
+++ b/managed/services/telemetry/mock_data_source_locator_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package telemetry
diff --git a/managed/services/telemetry/mock_data_source_test.go b/managed/services/telemetry/mock_data_source_test.go
index e31e6a6cd2..fb3a5a319c 100644
--- a/managed/services/telemetry/mock_data_source_test.go
+++ b/managed/services/telemetry/mock_data_source_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package telemetry
diff --git a/managed/services/telemetry/mock_distribution_util_service_test.go b/managed/services/telemetry/mock_distribution_util_service_test.go
index 6791db614d..f84650c94d 100644
--- a/managed/services/telemetry/mock_distribution_util_service_test.go
+++ b/managed/services/telemetry/mock_distribution_util_service_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package telemetry
diff --git a/managed/services/telemetry/mock_sender_test.go b/managed/services/telemetry/mock_sender_test.go
index fe335c60cf..7a81a50153 100644
--- a/managed/services/telemetry/mock_sender_test.go
+++ b/managed/services/telemetry/mock_sender_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package telemetry
diff --git a/managed/services/telemetry/telemetry.go b/managed/services/telemetry/telemetry.go
index 9e9ebdd142..99b491b0e9 100644
--- a/managed/services/telemetry/telemetry.go
+++ b/managed/services/telemetry/telemetry.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -63,7 +63,7 @@ type Service struct {
dus distributionUtilService
}
-// check interfaces
+// check interfaces.
var (
_ DataSourceLocator = (*Service)(nil)
)
@@ -169,7 +169,7 @@ func (s *Service) DistributionMethod() serverpb.DistributionMethod {
func (s *Service) processSendCh(ctx context.Context) {
var reportsBufSync sync.Mutex
var reportsBuf []*pmmv1.ServerMetric
- var sendCtx context.Context
+ var sendCtx context.Context //nolint:contextcheck
var cancel context.CancelFunc
for {
@@ -188,8 +188,8 @@ func (s *Service) processSendCh(ctx context.Context) {
reportsBuf = []*pmmv1.ServerMetric{}
reportsBufSync.Unlock()
- go func() {
- err := s.send(sendCtx, &reporter.ReportRequest{
+ go func(ctx context.Context) {
+ err := s.send(ctx, &reporter.ReportRequest{
Metrics: reportsToSend,
})
if err != nil {
@@ -201,7 +201,7 @@ func (s *Service) processSendCh(ctx context.Context) {
}
s.l.Debug("Telemetry info sent.")
- }()
+ }(sendCtx)
}
case <-ctx.Done():
if cancel != nil {
@@ -412,7 +412,7 @@ func (s *Service) Format(report *pmmv1.ServerMetric) string {
return builder.String()
}
-// GetSummaries returns the list of gathered telemetry
+// GetSummaries returns the list of gathered telemetry.
func (s *Service) GetSummaries() []string {
result := make([]string, 0, len(s.config.telemetry))
for _, c := range s.config.telemetry {
diff --git a/managed/services/telemetry/telemetry_test.go b/managed/services/telemetry/telemetry_test.go
index 477ff027d4..726e80cbaa 100644
--- a/managed/services/telemetry/telemetry_test.go
+++ b/managed/services/telemetry/telemetry_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -19,7 +19,6 @@ import (
"context"
"io/fs"
"os"
- "reflect"
"testing"
"time"
@@ -264,7 +263,7 @@ func initMockTelemetrySender(t *testing.T, expectedReport *reporter.ReportReques
var mockTelemetrySender mockSender
mockTelemetrySender.Test(t)
mockTelemetrySender.On("SendTelemetry",
- mock.AnythingOfType(reflect.TypeOf(context.TODO()).Name()),
+ mock.Anything,
mock.MatchedBy(func(report *reporter.ReportRequest) bool {
return matchExpectedReport(report, expectedReport)
}),
diff --git a/managed/services/telemetry/transform.go b/managed/services/telemetry/transform.go
index 95339047dd..b9ab4c7ac6 100644
--- a/managed/services/telemetry/transform.go
+++ b/managed/services/telemetry/transform.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/telemetry/transform_test.go b/managed/services/telemetry/transform_test.go
index 971e80ba4b..6e4e8f2cbc 100644
--- a/managed/services/telemetry/transform_test.go
+++ b/managed/services/telemetry/transform_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/types.go b/managed/services/types.go
index 49420c2841..4cac2c40ed 100644
--- a/managed/services/types.go
+++ b/managed/services/types.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -66,8 +66,6 @@ func (t *Target) Copy() Target {
type CheckResult struct {
CheckName string
AdvisorName string
- Silenced bool
- AlertID string
Interval check.Interval
Target Target
Result check.Result
diff --git a/managed/services/user/user.go b/managed/services/user/user.go
index cf986378a6..c0dd0d5365 100644
--- a/managed/services/user/user.go
+++ b/managed/services/user/user.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-// Package user provides API for user related tasks
+// Package user provides API for user related tasks.
package user
import (
@@ -55,7 +55,7 @@ func NewUserService(db *reform.DB, client grafanaClient) *Service {
return &s
}
-// GetUser creates a new user
+// GetUser creates a new user.
func (s *Service) GetUser(ctx context.Context, _ *userpb.UserDetailsRequest) (*userpb.UserDetailsResponse, error) {
userID, err := s.c.GetUserID(ctx)
if err != nil {
diff --git a/managed/services/utils.go b/managed/services/utils.go
deleted file mode 100644
index c67ba0518f..0000000000
--- a/managed/services/utils.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright (C) 2023 Percona LLC
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package services
-
-import (
- "github.com/percona-platform/saas/pkg/check"
- "github.com/sirupsen/logrus"
-)
-
-// GroupChecksByDB splits provided checks by database and returns three
-// slices: for MySQL, for PostgreSQL and for MongoDB.
-func GroupChecksByDB(
- l *logrus.Entry,
- checks map[string]check.Check,
-) (map[string]check.Check, map[string]check.Check, map[string]check.Check) {
- mySQLChecks := make(map[string]check.Check)
- postgreSQLChecks := make(map[string]check.Check)
- mongoDBChecks := make(map[string]check.Check)
- for _, c := range checks {
- switch c.Version {
- case 1:
- switch c.Type {
- case check.MySQLSelect:
- fallthrough
- case check.MySQLShow:
- mySQLChecks[c.Name] = c
-
- case check.PostgreSQLSelect:
- fallthrough
- case check.PostgreSQLShow:
- postgreSQLChecks[c.Name] = c
-
- case check.MongoDBGetParameter:
- fallthrough
- case check.MongoDBBuildInfo:
- fallthrough
- case check.MongoDBGetCmdLineOpts:
- fallthrough
- case check.MongoDBReplSetGetStatus:
- fallthrough
- case check.MongoDBGetDiagnosticData:
- mongoDBChecks[c.Name] = c
-
- default:
- l.Warnf("Unknown check type %s, skip it.", c.Type)
- }
- case 2:
- switch c.Family {
- case check.MySQL:
- mySQLChecks[c.Name] = c
- case check.PostgreSQL:
- postgreSQLChecks[c.Name] = c
- case check.MongoDB:
- mongoDBChecks[c.Name] = c
- default:
- l.Warnf("Unknown check family %s, skip it.", c.Family)
- }
- }
- }
-
- return mySQLChecks, postgreSQLChecks, mongoDBChecks
-}
diff --git a/managed/services/utils_test.go b/managed/services/utils_test.go
deleted file mode 100644
index a8d1623784..0000000000
--- a/managed/services/utils_test.go
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright (C) 2017 Percona LLC
-//
-// This program is free software: you can redistribute it and/or modify
-// it under the terms of the GNU Affero General Public License as published by
-// the Free Software Foundation, either version 3 of the License, or
-// (at your option) any later version.
-//
-// This program is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// GNU Affero General Public License for more details.
-//
-// You should have received a copy of the GNU Affero General Public License
-// along with this program. If not, see .
-
-package services
-
-import (
- "testing"
-
- "github.com/percona-platform/saas/pkg/check"
- "github.com/sirupsen/logrus"
- "github.com/stretchr/testify/assert"
- "github.com/stretchr/testify/require"
-)
-
-func TestGroupChecksByDB(t *testing.T) {
- t.Parallel()
-
- checks := map[string]check.Check{
- "MySQLShow": {Name: "MySQLShow", Version: 1, Type: check.MySQLShow},
- "MySQLSelect": {Name: "MySQLSelect", Version: 1, Type: check.MySQLSelect},
- "PostgreSQLShow": {Name: "PostgreSQLShow", Version: 1, Type: check.PostgreSQLShow},
- "PostgreSQLSelect": {Name: "PostgreSQLSelect", Version: 1, Type: check.PostgreSQLSelect},
- "MongoDBGetParameter": {Name: "MongoDBGetParameter", Version: 1, Type: check.MongoDBGetParameter},
- "MongoDBBuildInfo": {Name: "MongoDBBuildInfo", Version: 1, Type: check.MongoDBBuildInfo},
- "MongoDBGetCmdLineOpts": {Name: "MongoDBGetCmdLineOpts", Version: 1, Type: check.MongoDBGetCmdLineOpts},
- "MongoDBReplSetGetStatus": {Name: "MongoDBReplSetGetStatus", Version: 1, Type: check.MongoDBReplSetGetStatus},
- "MongoDBGetDiagnosticData": {Name: "MongoDBGetDiagnosticData", Version: 1, Type: check.MongoDBGetDiagnosticData},
- "unsupported type": {Name: "unsupported type", Version: 1, Type: check.Type("RedisInfo")},
- "missing type": {Name: "missing type", Version: 1},
- "MySQL family V2": {Name: "MySQL family V2", Version: 2, Family: check.MySQL},
- "PostgreSQL family V2": {Name: "PostgreSQL family V2", Version: 2, Family: check.PostgreSQL},
- "MongoDB family V2": {Name: "MongoDB family V2", Version: 2, Family: check.MongoDB},
- "missing family": {Name: "missing family", Version: 2},
- }
-
- l := logrus.WithField("component", "tests")
- mySQLChecks, postgreSQLChecks, mongoDBChecks := GroupChecksByDB(l, checks)
-
- require.Len(t, mySQLChecks, 3)
- require.Len(t, postgreSQLChecks, 3)
- require.Len(t, mongoDBChecks, 6)
-
- // V1 checks
- assert.Equal(t, check.MySQLShow, mySQLChecks["MySQLShow"].Type)
- assert.Equal(t, check.MySQLSelect, mySQLChecks["MySQLSelect"].Type)
-
- assert.Equal(t, check.PostgreSQLShow, postgreSQLChecks["PostgreSQLShow"].Type)
- assert.Equal(t, check.PostgreSQLSelect, postgreSQLChecks["PostgreSQLSelect"].Type)
-
- assert.Equal(t, check.MongoDBGetParameter, mongoDBChecks["MongoDBGetParameter"].Type)
- assert.Equal(t, check.MongoDBBuildInfo, mongoDBChecks["MongoDBBuildInfo"].Type)
- assert.Equal(t, check.MongoDBGetCmdLineOpts, mongoDBChecks["MongoDBGetCmdLineOpts"].Type)
- assert.Equal(t, check.MongoDBReplSetGetStatus, mongoDBChecks["MongoDBReplSetGetStatus"].Type)
- assert.Equal(t, check.MongoDBGetDiagnosticData, mongoDBChecks["MongoDBGetDiagnosticData"].Type)
-
- // V2 checks
- assert.Equal(t, check.MySQL, mySQLChecks["MySQL family V2"].Family)
- assert.Equal(t, check.PostgreSQL, postgreSQLChecks["PostgreSQL family V2"].Family)
- assert.Equal(t, check.MongoDB, mongoDBChecks["MongoDB family V2"].Family)
-}
diff --git a/managed/services/versioncache/mock_versioner_test.go b/managed/services/versioncache/mock_versioner_test.go
index b580c766ed..fe21715e30 100644
--- a/managed/services/versioncache/mock_versioner_test.go
+++ b/managed/services/versioncache/mock_versioner_test.go
@@ -1,4 +1,4 @@
-// Code generated by mockery v2.30.16. DO NOT EDIT.
+// Code generated by mockery v2.33.0. DO NOT EDIT.
package versioncache
diff --git a/managed/services/versioncache/versioncache.go b/managed/services/versioncache/versioncache.go
index aaa4d006b6..e51dfe6506 100644
--- a/managed/services/versioncache/versioncache.go
+++ b/managed/services/versioncache/versioncache.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/versioncache/versioncache_test.go b/managed/services/versioncache/versioncache_test.go
index d9fb69ce3f..1fadc032f6 100644
--- a/managed/services/versioncache/versioncache_test.go
+++ b/managed/services/versioncache/versioncache_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/victoriametrics/prometheus.go b/managed/services/victoriametrics/prometheus.go
index 304c20742c..717868763f 100644
--- a/managed/services/victoriametrics/prometheus.go
+++ b/managed/services/victoriametrics/prometheus.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/victoriametrics/scrape_configs.go b/managed/services/victoriametrics/scrape_configs.go
index 977a7b5dbd..e47df63673 100644
--- a/managed/services/victoriametrics/scrape_configs.go
+++ b/managed/services/victoriametrics/scrape_configs.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/victoriametrics/scrape_configs_test.go b/managed/services/victoriametrics/scrape_configs_test.go
index 7969431400..29d08272dc 100644
--- a/managed/services/victoriametrics/scrape_configs_test.go
+++ b/managed/services/victoriametrics/scrape_configs_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/victoriametrics/victoriametrics.go b/managed/services/victoriametrics/victoriametrics.go
index 13a468be87..746e3008d7 100644
--- a/managed/services/victoriametrics/victoriametrics.go
+++ b/managed/services/victoriametrics/victoriametrics.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -46,10 +46,6 @@ const (
updateBatchDelay = time.Second
configurationUpdateTimeout = 3 * time.Second
- // BasePrometheusConfigPath - basic path with prometheus config,
- // that user can mount to container.
- BasePrometheusConfigPath = "/srv/prometheus/prometheus.base.yml"
-
victoriametricsDir = "/srv/victoriametrics"
victoriametricsDataDir = "/srv/victoriametrics/data"
dirPerm = os.FileMode(0o775)
@@ -64,15 +60,15 @@ type Service struct {
baseURL *url.URL
client *http.Client
- baseConfigPath string // for testing
+ params *models.VictoriaMetricsParams
l *logrus.Entry
reloadCh chan struct{}
}
// NewVictoriaMetrics creates new VictoriaMetrics service.
-func NewVictoriaMetrics(scrapeConfigPath string, db *reform.DB, baseURL string, params *models.VictoriaMetricsParams) (*Service, error) {
- u, err := url.Parse(baseURL)
+func NewVictoriaMetrics(scrapeConfigPath string, db *reform.DB, params *models.VictoriaMetricsParams) (*Service, error) {
+ u, err := url.Parse(params.URL())
if err != nil {
return nil, errors.WithStack(err)
}
@@ -82,7 +78,7 @@ func NewVictoriaMetrics(scrapeConfigPath string, db *reform.DB, baseURL string,
db: db,
baseURL: u,
client: &http.Client{}, // TODO instrument with utils/irt; see vmalert package https://jira.percona.com/browse/PMM-7229
- baseConfigPath: params.BaseConfigPath,
+ params: params,
l: logrus.WithField("component", "victoriametrics"),
reloadCh: make(chan struct{}, 1),
}, nil
@@ -145,6 +141,9 @@ func (svc *Service) RequestConfigurationUpdate() {
// updateConfiguration updates VictoriaMetrics configuration.
func (svc *Service) updateConfiguration(ctx context.Context) error {
+ if svc.params.ExternalVM() {
+ return nil
+ }
start := time.Now()
defer func() {
if dur := time.Since(start); dur > time.Second {
@@ -152,8 +151,7 @@ func (svc *Service) updateConfiguration(ctx context.Context) error {
}
}()
- base := svc.loadBaseConfig()
- cfg, err := svc.marshalConfig(base)
+ cfg, err := svc.buildVMConfig()
if err != nil {
return err
}
@@ -161,6 +159,11 @@ func (svc *Service) updateConfiguration(ctx context.Context) error {
return svc.configAndReload(ctx, cfg)
}
+func (svc *Service) buildVMConfig() ([]byte, error) {
+ base := svc.loadBaseConfig()
+ return svc.marshalConfig(base)
+}
+
// reload asks VictoriaMetrics to reload configuration.
func (svc *Service) reload(ctx context.Context) error {
u := *svc.baseURL
@@ -189,10 +192,10 @@ func (svc *Service) reload(ctx context.Context) error {
// loadBaseConfig returns parsed base configuration file, or empty configuration on error.
func (svc *Service) loadBaseConfig() *config.Config {
- buf, err := os.ReadFile(svc.baseConfigPath)
+ buf, err := os.ReadFile(svc.params.BaseConfigPath)
if err != nil {
if !os.IsNotExist(err) {
- svc.l.Errorf("Failed to load base VictoriaMetrics config %s: %s", svc.baseConfigPath, err)
+ svc.l.Errorf("Failed to load base VictoriaMetrics config %s: %s", svc.params.BaseConfigPath, err)
}
return &config.Config{}
@@ -200,7 +203,7 @@ func (svc *Service) loadBaseConfig() *config.Config {
var cfg config.Config
if err := yaml.Unmarshal(buf, &cfg); err != nil {
- svc.l.Errorf("Failed to parse base VictoriaMetrics config %s: %s.", svc.baseConfigPath, err)
+ svc.l.Errorf("Failed to parse base VictoriaMetrics config %s: %s.", svc.params.BaseConfigPath, err)
return &config.Config{}
}
@@ -330,7 +333,10 @@ func (svc *Service) populateConfig(cfg *config.Config) error {
if cfg.GlobalConfig.ScrapeTimeout == 0 {
cfg.GlobalConfig.ScrapeTimeout = ScrapeTimeout(s.LR)
}
- cfg.ScrapeConfigs = append(cfg.ScrapeConfigs, scrapeConfigForVictoriaMetrics(s.HR))
+ cfg.ScrapeConfigs = append(cfg.ScrapeConfigs, scrapeConfigForVictoriaMetrics(svc.l, s.HR, svc.params))
+ if svc.params.ExternalVM() {
+ cfg.ScrapeConfigs = append(cfg.ScrapeConfigs, scrapeConfigForInternalVMAgent(s.HR, svc.baseURL.Host))
+ }
cfg.ScrapeConfigs = append(cfg.ScrapeConfigs, scrapeConfigForVMAlert(s.HR))
AddInternalServicesToScrape(cfg, s, settings.DBaaS.Enabled)
return AddScrapeConfigs(svc.l, cfg, tx.Querier, &s, nil, false)
@@ -338,17 +344,41 @@ func (svc *Service) populateConfig(cfg *config.Config) error {
}
// scrapeConfigForVictoriaMetrics returns scrape config for Victoria Metrics in Prometheus format.
-func scrapeConfigForVictoriaMetrics(interval time.Duration) *config.ScrapeConfig {
+func scrapeConfigForVictoriaMetrics(l *logrus.Entry, interval time.Duration, vmParams *models.VictoriaMetricsParams) *config.ScrapeConfig {
+ target, err := vmParams.URLFor("metrics")
+ if err != nil {
+ l.Errorf("couldn't parse relative path to victoria metrics: %q", err)
+ return nil
+ }
+
return &config.ScrapeConfig{
JobName: "victoriametrics",
ScrapeInterval: config.Duration(interval),
ScrapeTimeout: ScrapeTimeout(interval),
- MetricsPath: "/prometheus/metrics",
+ MetricsPath: target.Path,
ServiceDiscoveryConfig: config.ServiceDiscoveryConfig{
StaticConfigs: []*config.Group{
{
- Targets: []string{"127.0.0.1:9090"},
- Labels: map[string]string{"instance": "pmm-server"},
+ Targets: []string{target.Host},
+ Labels: map[string]string{"instance": models.PMMServerAgentID},
+ },
+ },
+ },
+ }
+}
+
+// scrapeConfigForInternalVMAgent returns scrape config for internal VM Agent in Prometheus format.
+func scrapeConfigForInternalVMAgent(interval time.Duration, target string) *config.ScrapeConfig {
+ return &config.ScrapeConfig{
+ JobName: "vmagent",
+ ScrapeInterval: config.Duration(interval),
+ ScrapeTimeout: ScrapeTimeout(interval),
+ MetricsPath: "/metrics",
+ ServiceDiscoveryConfig: config.ServiceDiscoveryConfig{
+ StaticConfigs: []*config.Group{
+ {
+ Targets: []string{target},
+ Labels: map[string]string{"instance": models.PMMServerAgentID},
},
},
},
@@ -375,6 +405,9 @@ func scrapeConfigForVMAlert(interval time.Duration) *config.ScrapeConfig {
// BuildScrapeConfigForVMAgent builds scrape configuration for given pmm-agent.
func (svc *Service) BuildScrapeConfigForVMAgent(pmmAgentID string) ([]byte, error) {
+ if pmmAgentID == models.PMMServerAgentID {
+ return svc.buildVMConfig()
+ }
var cfg config.Config
e := svc.db.InTransaction(func(tx *reform.TX) error {
settings, err := models.GetSettings(tx)
@@ -393,6 +426,10 @@ func (svc *Service) BuildScrapeConfigForVMAgent(pmmAgentID string) ([]byte, erro
// IsReady verifies that VictoriaMetrics works.
func (svc *Service) IsReady(ctx context.Context) error {
+ if svc.params.ExternalVM() {
+ svc.l.Debugf("External VM is used, VM healthcheck is skipped")
+ return nil
+ }
u := *svc.baseURL
u.Path = path.Join(u.Path, "health")
req, err := http.NewRequestWithContext(ctx, http.MethodGet, u.String(), nil)
diff --git a/managed/services/victoriametrics/victoriametrics_test.go b/managed/services/victoriametrics/victoriametrics_test.go
index 6eb19fcd9c..d6a7db56cb 100644
--- a/managed/services/victoriametrics/victoriametrics_test.go
+++ b/managed/services/victoriametrics/victoriametrics_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -43,8 +43,9 @@ func setup(t *testing.T) (*reform.DB, *Service, []byte) {
sqlDB := testdb.Open(t, models.SkipFixtures, nil)
db := reform.NewDB(sqlDB, postgresql.Dialect, reform.NewPrintfLogger(t.Logf))
- vmParams := &models.VictoriaMetricsParams{BaseConfigPath: "/srv/prometheus/prometheus.base.yml"}
- svc, err := NewVictoriaMetrics(configPath, db, "http://127.0.0.1:9090/prometheus/", vmParams)
+ vmParams, err := models.NewVictoriaMetricsParams(models.BasePrometheusConfigPath, models.VMBaseURL)
+ check.NoError(err)
+ svc, err := NewVictoriaMetrics(configPath, db, vmParams)
check.NoError(err)
original, err := os.ReadFile(configPath)
@@ -336,6 +337,7 @@ scrape_configs:
_service_label: bam
agent_id: /agent_id/cfec996c-4fe6-41d9-83cb-e1a3b1fe10a8
agent_type: mongodb_exporter
+ cluster: test-mongodb-noversion
instance: /agent_id/cfec996c-4fe6-41d9-83cb-e1a3b1fe10a8
node_id: /node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d
node_name: test-generic-node
@@ -366,6 +368,7 @@ scrape_configs:
_service_label: bam
agent_id: /agent_id/ecd8995a-d479-4b4d-bfb7-865bac4ac2fb
agent_type: mongodb_exporter
+ cluster: test-mongodb
instance: /agent_id/ecd8995a-d479-4b4d-bfb7-865bac4ac2fb
node_id: /node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d
node_name: test-generic-node
@@ -396,6 +399,7 @@ scrape_configs:
_service_label: bam
agent_id: /agent_id/ecd8995a-d479-4b4d-bfb7-865bac4ac2fb
agent_type: mongodb_exporter
+ cluster: test-mongodb
instance: /agent_id/ecd8995a-d479-4b4d-bfb7-865bac4ac2fb
node_id: /node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d
node_name: test-generic-node
@@ -428,6 +432,7 @@ scrape_configs:
_service_label: bar
agent_id: /agent_id/75bb30d3-ef4a-4147-97a8-621a996611dd
agent_type: mysqld_exporter
+ cluster: test-mysql
instance: /agent_id/75bb30d3-ef4a-4147-97a8-621a996611dd
node_id: /node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d
node_name: test-generic-node
@@ -465,6 +470,7 @@ scrape_configs:
_service_label: bar
agent_id: /agent_id/75bb30d3-ef4a-4147-97a8-621a996611dd
agent_type: mysqld_exporter
+ cluster: test-mysql
instance: /agent_id/75bb30d3-ef4a-4147-97a8-621a996611dd
node_id: /node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d
node_name: test-generic-node
@@ -508,6 +514,7 @@ scrape_configs:
_service_label: bar
agent_id: /agent_id/75bb30d3-ef4a-4147-97a8-621a996611dd
agent_type: mysqld_exporter
+ cluster: test-mysql
instance: /agent_id/75bb30d3-ef4a-4147-97a8-621a996611dd
node_id: /node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d
node_name: test-generic-node
@@ -540,6 +547,7 @@ scrape_configs:
_service_label: bar
agent_id: /agent_id/f9ab9f7b-5e53-4952-a2e7-ff25fb90fe6a
agent_type: mysqld_exporter
+ cluster: test-remote-mysql
instance: /agent_id/f9ab9f7b-5e53-4952-a2e7-ff25fb90fe6a
node_id: /node_id/4e2e07dc-40a1-18ca-aea9-d943260a9653
node_name: test-remote-node
@@ -577,6 +585,7 @@ scrape_configs:
_service_label: bar
agent_id: /agent_id/f9ab9f7b-5e53-4952-a2e7-ff25fb90fe6a
agent_type: mysqld_exporter
+ cluster: test-remote-mysql
instance: /agent_id/f9ab9f7b-5e53-4952-a2e7-ff25fb90fe6a
node_id: /node_id/4e2e07dc-40a1-18ca-aea9-d943260a9653
node_name: test-remote-node
@@ -620,6 +629,7 @@ scrape_configs:
_service_label: bar
agent_id: /agent_id/f9ab9f7b-5e53-4952-a2e7-ff25fb90fe6a
agent_type: mysqld_exporter
+ cluster: test-remote-mysql
instance: /agent_id/f9ab9f7b-5e53-4952-a2e7-ff25fb90fe6a
node_id: /node_id/4e2e07dc-40a1-18ca-aea9-d943260a9653
node_name: test-remote-node
@@ -652,6 +662,7 @@ scrape_configs:
_service_label: bar
agent_id: /agent_id/29e14468-d479-4b4d-bfb7-4ac2fb865bac
agent_type: postgres_exporter
+ cluster: test-postgresql
instance: /agent_id/29e14468-d479-4b4d-bfb7-4ac2fb865bac
node_id: /node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d
node_name: test-generic-node
@@ -681,6 +692,7 @@ scrape_configs:
_service_label: bar
agent_id: /agent_id/29e14468-d479-4b4d-bfb7-4ac2fb865bac
agent_type: postgres_exporter
+ cluster: test-postgresql
instance: /agent_id/29e14468-d479-4b4d-bfb7-4ac2fb865bac
node_id: /node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d
node_name: test-generic-node
@@ -710,6 +722,7 @@ scrape_configs:
_service_label: bar
agent_id: /agent_id/29e14468-d479-4b4d-bfb7-4ac2fb865bac
agent_type: postgres_exporter
+ cluster: test-postgresql
instance: /agent_id/29e14468-d479-4b4d-bfb7-4ac2fb865bac
node_id: /node_id/cc663f36-18ca-40a1-aea9-c6310bb4738d
node_name: test-generic-node
@@ -802,7 +815,7 @@ func TestBaseConfig(t *testing.T) {
db, svc, original := setup(t)
defer teardown(t, db, svc, original)
- svc.baseConfigPath = "../../testdata/victoriametrics/promscrape.base.yml"
+ svc.params.BaseConfigPath = "../../testdata/victoriametrics/promscrape.base.yml"
expected := strings.TrimSpace(`
# Managed by pmm-managed. DO NOT EDIT.
diff --git a/managed/services/vmalert/external_rules.go b/managed/services/vmalert/external_rules.go
index e87030895e..b60ff6d8e2 100644
--- a/managed/services/vmalert/external_rules.go
+++ b/managed/services/vmalert/external_rules.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/vmalert/init_test.go b/managed/services/vmalert/init_test.go
index bf9cffa913..d147f53360 100644
--- a/managed/services/vmalert/init_test.go
+++ b/managed/services/vmalert/init_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -15,7 +15,7 @@
package vmalert
-import "github.com/percona/pmm/managed/utils/logger"
+import "github.com/percona/pmm/utils/logger"
//nolint:gochecknoinits
func init() {
diff --git a/managed/services/vmalert/vmalert.go b/managed/services/vmalert/vmalert.go
index bc8c0f74b8..f5c86c03e0 100644
--- a/managed/services/vmalert/vmalert.go
+++ b/managed/services/vmalert/vmalert.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/services/vmalert/vmalert_test.go b/managed/services/vmalert/vmalert_test.go
index 47221fa94d..3d3da6afe9 100644
--- a/managed/services/vmalert/vmalert_test.go
+++ b/managed/services/vmalert/vmalert_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/testdata/supervisord.d/grafana.ini b/managed/testdata/supervisord.d/grafana.ini
index b3e4213506..c6a0788699 100644
--- a/managed/testdata/supervisord.d/grafana.ini
+++ b/managed/testdata/supervisord.d/grafana.ini
@@ -3,15 +3,9 @@
[program:grafana]
priority = 3
command =
- /usr/sbin/grafana-server
+ /usr/sbin/grafana server
--homepath=/usr/share/grafana
--config=/etc/grafana/grafana.ini
- cfg:default.paths.data=/srv/grafana
- cfg:default.paths.plugins=/srv/grafana/plugins
- cfg:default.paths.logs=/srv/logs
- cfg:default.log.mode=console
- cfg:default.log.console.format=console
- cfg:default.server.root_url="https://%%(domain)s/graph"
environment =
PERCONA_TEST_POSTGRES_ADDR="",
PERCONA_TEST_POSTGRES_DBNAME="",
diff --git a/managed/testdata/supervisord.d/pmm-db_disabled.ini b/managed/testdata/supervisord.d/pmm-db_disabled.ini
index 210d822422..b45251ab1f 100644
--- a/managed/testdata/supervisord.d/pmm-db_disabled.ini
+++ b/managed/testdata/supervisord.d/pmm-db_disabled.ini
@@ -61,7 +61,6 @@ priority = 14
command =
/usr/sbin/pmm-managed
--victoriametrics-config=/etc/victoriametrics-promscrape.yml
- --victoriametrics-url=http://127.0.0.1:9090/prometheus
--supervisord-config-dir=/etc/supervisord.d
autorestart = true
autostart = true
diff --git a/managed/testdata/supervisord.d/pmm-db_enabled.ini b/managed/testdata/supervisord.d/pmm-db_enabled.ini
index df0fd59059..4d4ad4afd9 100644
--- a/managed/testdata/supervisord.d/pmm-db_enabled.ini
+++ b/managed/testdata/supervisord.d/pmm-db_enabled.ini
@@ -85,7 +85,6 @@ priority = 14
command =
/usr/sbin/pmm-managed
--victoriametrics-config=/etc/victoriametrics-promscrape.yml
- --victoriametrics-url=http://127.0.0.1:9090/prometheus
--supervisord-config-dir=/etc/supervisord.d
autorestart = true
autostart = true
diff --git a/managed/testdata/supervisord.d/vmalert.ini b/managed/testdata/supervisord.d/vmalert.ini
index be3746ef3c..0d645ed111 100644
--- a/managed/testdata/supervisord.d/vmalert.ini
+++ b/managed/testdata/supervisord.d/vmalert.ini
@@ -7,11 +7,11 @@ command =
--notifier.url="http://127.0.0.1:9093/alertmanager,https://external-alertmanager:6443/alerts"
--notifier.basicAuth.password=',"passw!,ord"'
--notifier.basicAuth.username=",external-user"
- --external.url=http://localhost:9090/prometheus
- --datasource.url=http://127.0.0.1:9090/prometheus
- --remoteRead.url=http://127.0.0.1:9090/prometheus
+ --external.url=http://127.0.0.1:9090/prometheus/
+ --datasource.url=http://127.0.0.1:9090/prometheus/
+ --remoteRead.url=http://127.0.0.1:9090/prometheus/
--remoteRead.ignoreRestoreErrors=false
- --remoteWrite.url=http://127.0.0.1:9090/prometheus
+ --remoteWrite.url=http://127.0.0.1:9090/prometheus/
--rule=/srv/prometheus/rules/*.yml
--httpListenAddr=127.0.0.1:8880
user = pmm
diff --git a/managed/testdata/supervisord.d/vmproxy.ini b/managed/testdata/supervisord.d/vmproxy.ini
index 72acc05eaf..5654b85bc4 100644
--- a/managed/testdata/supervisord.d/vmproxy.ini
+++ b/managed/testdata/supervisord.d/vmproxy.ini
@@ -4,7 +4,7 @@
priority = 9
command =
/usr/sbin/vmproxy
- --target-url=http://127.0.0.1:9090/
+ --target-url=http://127.0.0.1:9090/prometheus/
--listen-port=8430
--listen-address=127.0.0.1
--header-name=X-Proxy-Filter
diff --git a/managed/utils/clean/clean.go b/managed/utils/clean/clean.go
index 8ca7e69aa6..2a319e165e 100644
--- a/managed/utils/clean/clean.go
+++ b/managed/utils/clean/clean.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/clean/clean_test.go b/managed/utils/clean/clean_test.go
index 8991b20850..95e2d6881e 100644
--- a/managed/utils/clean/clean_test.go
+++ b/managed/utils/clean/clean_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/collectors/collectors.go b/managed/utils/collectors/collectors.go
index f08905b150..66e464ff40 100644
--- a/managed/utils/collectors/collectors.go
+++ b/managed/utils/collectors/collectors.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/depstests/depstests.go b/managed/utils/depstests/depstests.go
index dd08cf3750..f7b17754f1 100644
--- a/managed/utils/depstests/depstests.go
+++ b/managed/utils/depstests/depstests.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/depstests/protobuf_test.go b/managed/utils/depstests/protobuf_test.go
index 7d1ecce53c..472c9fc4e3 100644
--- a/managed/utils/depstests/protobuf_test.go
+++ b/managed/utils/depstests/protobuf_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/dir/dir.go b/managed/utils/dir/dir.go
index bd5f7ceb59..7714b9025c 100644
--- a/managed/utils/dir/dir.go
+++ b/managed/utils/dir/dir.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/dir/dir_test.go b/managed/utils/dir/dir_test.go
index e23f8cea3e..8c05ccafb7 100644
--- a/managed/utils/dir/dir_test.go
+++ b/managed/utils/dir/dir_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/envvars/parser.go b/managed/utils/envvars/parser.go
index 33deb8679f..3e93bde76b 100644
--- a/managed/utils/envvars/parser.go
+++ b/managed/utils/envvars/parser.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -42,6 +42,7 @@ const (
envEnableAccessControl = "ENABLE_RBAC"
envPlatformAPITimeout = "PERCONA_PLATFORM_API_TIMEOUT"
defaultPlatformAPITimeout = 30 * time.Second
+ ENVvmAgentPrefix = "VMAGENT_"
)
// InvalidDurationError invalid duration error.
@@ -156,6 +157,12 @@ func ParseEnvVars(envs []string) (envSettings *models.ChangeSettingsParams, errs
case "PMM_PUBLIC_ADDRESS":
envSettings.PMMPublicAddress = v
+ case "PMM_VM_URL":
+ _, err = url.Parse(v)
+ if err != nil {
+ err = fmt.Errorf("invalid value %q for environment variable %q", v, k)
+ }
+
case "NO_PROXY", "HTTP_PROXY", "HTTPS_PROXY":
continue
@@ -203,6 +210,11 @@ func ParseEnvVars(envs []string) (envSettings *models.ChangeSettingsParams, errs
continue
}
+ // skip VM Agents environment variables
+ if strings.HasPrefix(k, ENVvmAgentPrefix) {
+ continue
+ }
+
// skip supervisord environment variables
if strings.HasPrefix(k, "SUPERVISOR_") {
continue
diff --git a/managed/utils/envvars/parser_test.go b/managed/utils/envvars/parser_test.go
index 6bb5d91a83..2d823ea055 100644
--- a/managed/utils/envvars/parser_test.go
+++ b/managed/utils/envvars/parser_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/interceptors/grpc_extension.go b/managed/utils/interceptors/grpc_extension.go
index 83455c85e5..19046adefc 100644
--- a/managed/utils/interceptors/grpc_extension.go
+++ b/managed/utils/interceptors/grpc_extension.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -32,7 +32,7 @@ const (
externalCallerOrigin = callerOrigin("external")
)
-// GRPCMetricsExtension for extra labels in /debug/metrics
+// GRPCMetricsExtension for extra labels in /debug/metrics.
type GRPCMetricsExtension struct {
grpc_prometheus.DefaultExtension
}
diff --git a/managed/utils/interceptors/interceptors.go b/managed/utils/interceptors/interceptors.go
index a1c466dcbd..039de49143 100644
--- a/managed/utils/interceptors/interceptors.go
+++ b/managed/utils/interceptors/interceptors.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -32,7 +32,7 @@ import (
"google.golang.org/grpc/status"
"github.com/percona/pmm/api/agentpb"
- "github.com/percona/pmm/managed/utils/logger"
+ "github.com/percona/pmm/utils/logger"
)
func logRequest(l *logrus.Entry, prefix string, f func() error) (err error) {
@@ -142,7 +142,7 @@ func Stream(interceptor grpc.StreamServerInterceptor) func(srv interface{}, ss g
}
}
-// check interfaces
+// check interfaces.
var (
_ grpc.UnaryServerInterceptor = Unary(nil)
_ grpc.StreamServerInterceptor = Stream(nil)
diff --git a/managed/utils/interceptors/middlewares.go b/managed/utils/interceptors/middlewares.go
index 6fa1a82837..fdd9e0d581 100644
--- a/managed/utils/interceptors/middlewares.go
+++ b/managed/utils/interceptors/middlewares.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/interceptors/service.go b/managed/utils/interceptors/service.go
index cf47ebd6de..86c5040e41 100644
--- a/managed/utils/interceptors/service.go
+++ b/managed/utils/interceptors/service.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/irt/logger.go b/managed/utils/irt/logger.go
index cbaa896b91..5a28fe31b0 100644
--- a/managed/utils/irt/logger.go
+++ b/managed/utils/irt/logger.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/irt/metrics.go b/managed/utils/irt/metrics.go
index 19c9876ee0..57a72ebc03 100644
--- a/managed/utils/irt/metrics.go
+++ b/managed/utils/irt/metrics.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -75,7 +75,7 @@ func (m *metrics) Collect(ch chan<- prom.Metric) {
m.duration.Collect(ch)
}
-// check interfaces
+// check interfaces.
var (
_ prom.Collector = (*metrics)(nil)
)
diff --git a/managed/utils/platform/client.go b/managed/utils/platform/client.go
index e6367d910d..c199e501e0 100644
--- a/managed/utils/platform/client.go
+++ b/managed/utils/platform/client.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/pprof/pprof.go b/managed/utils/pprof/pprof.go
index 007a8b39f3..71c5687c76 100644
--- a/managed/utils/pprof/pprof.go
+++ b/managed/utils/pprof/pprof.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/pprof/pprof_test.go b/managed/utils/pprof/pprof_test.go
index f80204a99a..1dcc59a4ba 100644
--- a/managed/utils/pprof/pprof_test.go
+++ b/managed/utils/pprof/pprof_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/signatures/signatures.go b/managed/utils/signatures/signatures.go
index d5e4f9e02a..8d6d905d29 100644
--- a/managed/utils/signatures/signatures.go
+++ b/managed/utils/signatures/signatures.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/signatures/signatures_test.go b/managed/utils/signatures/signatures_test.go
index af86cf0fd8..9e8935421e 100644
--- a/managed/utils/signatures/signatures_test.go
+++ b/managed/utils/signatures/signatures_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/stringset/stringset.go b/managed/utils/stringset/stringset.go
index 548f07ad4f..b59b3c02af 100644
--- a/managed/utils/stringset/stringset.go
+++ b/managed/utils/stringset/stringset.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/testdb/db.go b/managed/utils/testdb/db.go
index 1a2354ff9f..d5707e367a 100644
--- a/managed/utils/testdb/db.go
+++ b/managed/utils/testdb/db.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/tests/asserts.go b/managed/utils/tests/asserts.go
index 6371f8dc46..cb52d9296a 100644
--- a/managed/utils/tests/asserts.go
+++ b/managed/utils/tests/asserts.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/tests/aws.go b/managed/utils/tests/aws.go
index 8537fa1a72..ed003a2350 100644
--- a/managed/utils/tests/aws.go
+++ b/managed/utils/tests/aws.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/tests/credentials.go b/managed/utils/tests/credentials.go
index cac0241de7..8d5852ec73 100644
--- a/managed/utils/tests/credentials.go
+++ b/managed/utils/tests/credentials.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/tests/fuzz.go b/managed/utils/tests/fuzz.go
index 36dd4f4583..918e7c5bd9 100644
--- a/managed/utils/tests/fuzz.go
+++ b/managed/utils/tests/fuzz.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/tests/id.go b/managed/utils/tests/id.go
index b02ab45804..d49ccc706e 100644
--- a/managed/utils/tests/id.go
+++ b/managed/utils/tests/id.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -52,7 +52,7 @@ func SetTestIDReader(t *testing.T) {
t.Cleanup(func() { uuid.SetRand(nil) })
}
-// check interfaces
+// check interfaces.
var (
_ io.Reader = (*IDReader)(nil)
)
diff --git a/managed/utils/validators/alerting_rules.go b/managed/utils/validators/alerting_rules.go
index 81fb8aa66f..d00de9a17f 100644
--- a/managed/utils/validators/alerting_rules.go
+++ b/managed/utils/validators/alerting_rules.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/validators/alerting_rules_test.go b/managed/utils/validators/alerting_rules_test.go
index 859dde22d7..ed40d7daff 100644
--- a/managed/utils/validators/alerting_rules_test.go
+++ b/managed/utils/validators/alerting_rules_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/managed/utils/validators/validators.go b/managed/utils/validators/validators.go
index 7257cf917e..8a4fd3d983 100644
--- a/managed/utils/validators/validators.go
+++ b/managed/utils/validators/validators.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/db.go b/qan-api2/db.go
index de3ed9d776..8c87408258 100644
--- a/qan-api2/db.go
+++ b/qan-api2/db.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/db_test.go b/qan-api2/db_test.go
index 1eb145ea93..fc06a5fd7d 100644
--- a/qan-api2/db_test.go
+++ b/qan-api2/db_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/exporters/slow_log.go b/qan-api2/exporters/slow_log.go
index e13c81e03f..db3d6cd0cc 100644
--- a/qan-api2/exporters/slow_log.go
+++ b/qan-api2/exporters/slow_log.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/main.go b/qan-api2/main.go
index 9d94f52758..c155e85c1e 100644
--- a/qan-api2/main.go
+++ b/qan-api2/main.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -27,8 +27,6 @@ import (
_ "net/http/pprof" //nolint:gosec
"os"
"os/signal"
- "path/filepath"
- "runtime"
"strings"
"sync"
"time"
@@ -56,7 +54,7 @@ import (
aservice "github.com/percona/pmm/qan-api2/services/analytics"
rservice "github.com/percona/pmm/qan-api2/services/receiver"
"github.com/percona/pmm/qan-api2/utils/interceptors"
- "github.com/percona/pmm/qan-api2/utils/logger"
+ "github.com/percona/pmm/utils/logger"
"github.com/percona/pmm/utils/sqlmetrics"
"github.com/percona/pmm/version"
)
@@ -278,25 +276,7 @@ func main() {
log.Printf("%s.", version.ShortInfo())
- logrus.SetFormatter(&logrus.TextFormatter{
- // Enable multiline-friendly formatter in both development (with terminal) and production (without terminal):
- // https://github.com/sirupsen/logrus/blob/839c75faf7f98a33d445d181f3018b5c3409a45e/text_formatter.go#L176-L178
- ForceColors: true,
- FullTimestamp: true,
- TimestampFormat: "2006-01-02T15:04:05.000-07:00",
-
- CallerPrettyfier: func(f *runtime.Frame) (string, string) {
- _, function := filepath.Split(f.Function)
-
- // keep a single directory name as a compromise between brevity and unambiguity
- var dir string
- dir, file := filepath.Split(f.File)
- dir = filepath.Base(dir)
- file = fmt.Sprintf("%s/%s:%d", dir, file, f.Line)
-
- return function, file
- },
- })
+ logger.SetupGlobalLogger()
if *debugF {
logrus.SetLevel(logrus.DebugLevel)
diff --git a/qan-api2/maincover_test.go b/qan-api2/maincover_test.go
index 1828a08ed0..4f5accd141 100644
--- a/qan-api2/maincover_test.go
+++ b/qan-api2/maincover_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/models/base.go b/qan-api2/models/base.go
index 4f0368d8aa..45a3493b98 100644
--- a/qan-api2/models/base.go
+++ b/qan-api2/models/base.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/models/data_ingestion.go b/qan-api2/models/data_ingestion.go
index 126052c9b4..d6eda35ba5 100644
--- a/qan-api2/models/data_ingestion.go
+++ b/qan-api2/models/data_ingestion.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -509,7 +509,7 @@ type MetricsBucketExtended struct {
*qanpb.MetricsBucket
}
-// MetricsBucket implements models to store metrics bucket
+// MetricsBucket implements models to store metrics bucket.
type MetricsBucket struct {
db *sqlx.DB
l *logrus.Entry
@@ -747,7 +747,7 @@ func mapToArrsIntInt(m map[uint64]uint64) ([]uint64, []uint64) {
return keys, values
}
-// check interfaces
+// check interfaces.
var (
_ prometheus.Collector = (*MetricsBucket)(nil)
)
diff --git a/qan-api2/models/metrics.go b/qan-api2/models/metrics.go
index 099465cc04..70dac41689 100644
--- a/qan-api2/models/metrics.go
+++ b/qan-api2/models/metrics.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -23,6 +23,7 @@ import (
"fmt"
"log"
"sort"
+ "strings"
"text/template"
"time"
@@ -977,7 +978,53 @@ func (m *Metrics) QueryExists(ctx context.Context, serviceID, query string) (boo
return false, nil
}
-const queryByQueryIDTmpl = `SELECT explain_fingerprint, fingerprint, placeholders_count FROM metrics
+const schemaByQueryIDTmpl = `SELECT schema FROM metrics
+WHERE service_id = :service_id AND queryid = :query_id LIMIT 1;`
+
+// SchemaByQueryID returns schema for given queryID and serviceID.
+func (m *Metrics) SchemaByQueryID(ctx context.Context, serviceID, queryID string) (*qanpb.SchemaByQueryIDReply, error) {
+ arg := map[string]interface{}{
+ "service_id": serviceID,
+ "query_id": queryID,
+ }
+
+ var queryBuffer bytes.Buffer
+ queryBuffer.WriteString(schemaByQueryIDTmpl)
+
+ query, args, err := sqlx.Named(queryBuffer.String(), arg)
+ if err != nil {
+ return nil, errors.Wrap(err, cannotPrepare)
+ }
+ query, args, err = sqlx.In(query, args...)
+ if err != nil {
+ return nil, errors.Wrap(err, cannotPopulate)
+ }
+ query = m.db.Rebind(query)
+
+ queryCtx, cancel := context.WithTimeout(ctx, queryTimeout)
+ defer cancel()
+
+ rows, err := m.db.QueryxContext(queryCtx, query, args...)
+ if err != nil {
+ return nil, errors.Wrap(err, cannotExecute)
+ }
+ defer rows.Close() //nolint:errcheck
+
+ res := &qanpb.SchemaByQueryIDReply{}
+ for rows.Next() {
+ err = rows.Scan(&res.Schema)
+
+ if err != nil {
+ return res, errors.Wrap(err, "failed to scan query")
+ }
+
+ return res, nil //nolint:staticcheck
+ }
+
+ return res, nil
+}
+
+const queryByQueryIDTmpl = `SELECT explain_fingerprint, fingerprint, example, placeholders_count FROM metrics
WHERE service_id = :service_id AND queryid = :query_id LIMIT 1;
`
@@ -1011,17 +1058,25 @@ func (m *Metrics) ExplainFingerprintByQueryID(ctx context.Context, serviceID, qu
}
defer rows.Close() //nolint:errcheck
- var fingerprint string
+ var fingerprint, example string
for rows.Next() {
err = rows.Scan(
&res.ExplainFingerprint,
&fingerprint,
+ &example,
&res.PlaceholdersCount)
if err != nil {
return res, errors.Wrap(err, "failed to scan query")
}
+ if example != "" {
+ res.ExplainFingerprint = example
+ res.PlaceholdersCount = 0
+
+ return res, nil
+ }
+
if res.ExplainFingerprint == "" {
res.ExplainFingerprint = fingerprint
}
@@ -1033,18 +1088,16 @@ func (m *Metrics) ExplainFingerprintByQueryID(ctx context.Context, serviceID, qu
}
const selectedQueryMetadataTmpl = `
-SELECT any(service_name),
- any(database),
- any(schema),
- any(username),
- any(replication_set),
- any(cluster),
- any(service_type),
- any(service_id),
- any(environment),
- any(node_id),
- any(node_name),
- any(node_type)
+SELECT DISTINCT service_name,
+ database,
+ schema,
+ username,
+ replication_set,
+ cluster,
+ service_type,
+ environment,
+ node_name,
+ node_type
FROM metrics
WHERE period_start >= :period_start_from AND period_start <= :period_start_to
{{ if not .Totals }} AND {{ .Group }} = '{{ .DimensionVal }}'
@@ -1058,10 +1111,7 @@ WHERE period_start >= :period_start_from AND period_start <= :period_start_to
AND ({{range $key, $vals := .Labels }}{{ $i = inc $i}}
{{ if gt $i 1}} OR {{ end }} has(['{{ StringsJoin $vals "', '" }}'], labels.value[indexOf(labels.key, '{{ $key }}')])
{{ end }})
-{{ end }}
-{{ if not .Totals }} GROUP BY {{ .Group }}
{{ end }}
-WITH TOTALS;
`
// GetSelectedQueryMetadata returns metadata for given query ID.
@@ -1120,26 +1170,57 @@ func (m *Metrics) GetSelectedQueryMetadata(ctx context.Context, periodStartFromS
}
defer rows.Close()
+ metadata := make(map[string]map[string]struct{})
+ columnNames, err := rows.Columns()
+ if err != nil {
+ return nil, errors.Wrap(err, "failed to get column names")
+ }
+ for _, name := range columnNames {
+ metadata[name] = make(map[string]struct{})
+ }
+
for rows.Next() {
- err = rows.Scan(
- &res.ServiceName,
- &res.Database,
- &res.Schema,
- &res.Username,
- &res.ReplicationSet,
- &res.Cluster,
- &res.ServiceType,
- &res.ServiceId,
- &res.Environment,
- &res.NodeId,
- &res.NodeName,
- &res.NodeType)
+ row := make([]any, len(columnNames))
+ for i := range columnNames {
+ row[i] = new(string)
+ }
+
+ err = rows.Scan(row...)
if err != nil {
- return res, errors.Wrap(err, "failed to scan query")
- } else {
- return res, nil
+ if errors.Is(err, sql.ErrNoRows) {
+ return nil, errors.Wrap(err, "query_id doesnt exists")
+ }
+ return nil, errors.Wrap(err, "failed to scan query")
+ }
+
+ for k, v := range row {
+ if value, ok := v.(*string); ok {
+ metadata[columnNames[k]][*value] = struct{}{}
+ }
}
}
- return res, errors.New("query_id doesnt exists")
+ res.ServiceName = prepareMetadataProperty(metadata["service_name"])
+ res.Database = prepareMetadataProperty(metadata["database"])
+ res.Schema = prepareMetadataProperty(metadata["schema"])
+ res.Username = prepareMetadataProperty(metadata["username"])
+ res.ReplicationSet = prepareMetadataProperty(metadata["replication_set"])
+ res.Cluster = prepareMetadataProperty(metadata["cluster"])
+ res.ServiceType = prepareMetadataProperty(metadata["service_type"])
+ res.Environment = prepareMetadataProperty(metadata["environment"])
+ res.NodeName = prepareMetadataProperty(metadata["node_name"])
+ res.NodeType = prepareMetadataProperty(metadata["node_type"])
+
+ return res, nil
+}
+
+func prepareMetadataProperty(metadata map[string]struct{}) string {
+ res := []string{}
+ for k := range metadata {
+ res = append(res, k)
+ }
+
+ sort.Strings(res)
+
+ return strings.Join(res, ", ")
}
diff --git a/qan-api2/models/reporter.go b/qan-api2/models/reporter.go
index 4ceebcd10f..4a5e463626 100644
--- a/qan-api2/models/reporter.go
+++ b/qan-api2/models/reporter.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/services/analytics/base.go b/qan-api2/services/analytics/base.go
index b9e9bd54e0..5d91cf5014 100644
--- a/qan-api2/services/analytics/base.go
+++ b/qan-api2/services/analytics/base.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/services/analytics/filters.go b/qan-api2/services/analytics/filters.go
index da6cdc9bfe..97d46ba1de 100644
--- a/qan-api2/services/analytics/filters.go
+++ b/qan-api2/services/analytics/filters.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/services/analytics/filters_test.go b/qan-api2/services/analytics/filters_test.go
index c7afc95c5a..31b4fb81f4 100644
--- a/qan-api2/services/analytics/filters_test.go
+++ b/qan-api2/services/analytics/filters_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -24,7 +24,7 @@ import (
"time"
_ "github.com/ClickHouse/clickhouse-go/151" // register database/sql driver
- // TODO replace with 'google.golang.org/protobuf/encoding/protojson' since this one is deprecated
+ // TODO replace with 'google.golang.org/protobuf/encoding/protojson' since this one is deprecated.
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/jmoiron/sqlx"
"github.com/stretchr/testify/assert"
diff --git a/qan-api2/services/analytics/metrics_names.go b/qan-api2/services/analytics/metrics_names.go
index 5d5074e0a3..4f913d80dd 100644
--- a/qan-api2/services/analytics/metrics_names.go
+++ b/qan-api2/services/analytics/metrics_names.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/services/analytics/metrics_names_test.go b/qan-api2/services/analytics/metrics_names_test.go
index b9ca476b6f..c7e8edc667 100644
--- a/qan-api2/services/analytics/metrics_names_test.go
+++ b/qan-api2/services/analytics/metrics_names_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/services/analytics/object_details.go b/qan-api2/services/analytics/object_details.go
index 79ffa56ea2..f3bdc191fb 100644
--- a/qan-api2/services/analytics/object_details.go
+++ b/qan-api2/services/analytics/object_details.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -377,3 +377,16 @@ func (s *Service) ExplainFingerprintByQueryID(ctx context.Context, in *qanpb.Exp
return res, nil
}
+
+// SchemaByQueryID returns schema for given queryID and serviceID.
+func (s *Service) SchemaByQueryID(ctx context.Context, in *qanpb.SchemaByQueryIDRequest) (*qanpb.SchemaByQueryIDReply, error) {
+ res, err := s.mm.SchemaByQueryID(
+ ctx,
+ in.ServiceId,
+ in.QueryId)
+ if err != nil {
+ return nil, fmt.Errorf("error in checking query:%w", err)
+ }
+
+ return res, nil
+}
diff --git a/qan-api2/services/analytics/object_details_test.go b/qan-api2/services/analytics/object_details_test.go
index 6a0173949c..05793dd581 100644
--- a/qan-api2/services/analytics/object_details_test.go
+++ b/qan-api2/services/analytics/object_details_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -21,7 +21,7 @@ import (
"testing"
"time"
- // TODO replace with 'google.golang.org/protobuf/encoding/protojson' since this one is deprecated
+ // TODO replace with 'google.golang.org/protobuf/encoding/protojson' since this one is deprecated.
"github.com/golang/protobuf/jsonpb" //nolint:staticcheck
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/stretchr/testify/assert"
diff --git a/qan-api2/services/analytics/profile.go b/qan-api2/services/analytics/profile.go
index de0e498254..d2cb850cda 100644
--- a/qan-api2/services/analytics/profile.go
+++ b/qan-api2/services/analytics/profile.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/services/analytics/profile_test.go b/qan-api2/services/analytics/profile_test.go
index 429a7c1211..895a7f4dfd 100644
--- a/qan-api2/services/analytics/profile_test.go
+++ b/qan-api2/services/analytics/profile_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -23,9 +23,9 @@ import (
"testing"
"time"
- // TODO replace with 'google.golang.org/protobuf/encoding/protojson' since this one is deprecated
+ // TODO replace with 'google.golang.org/protobuf/encoding/protojson' since this one is deprecated.
"github.com/golang/protobuf/jsonpb" //nolint:staticcheck
- // TODO replace with 'google.golang.org/protobuf/proto' since this one is deprecated
+ // TODO replace with 'google.golang.org/protobuf/proto' since this one is deprecated.
"github.com/golang/protobuf/proto" //nolint:staticcheck
"github.com/golang/protobuf/ptypes/timestamp"
"github.com/jmoiron/sqlx"
diff --git a/qan-api2/services/receiver/receiver.go b/qan-api2/services/receiver/receiver.go
index 4d963dd2b7..127f4c0fba 100644
--- a/qan-api2/services/receiver/receiver.go
+++ b/qan-api2/services/receiver/receiver.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/qan-api2/test_data/GetMetrics_group_by_queryid.json b/qan-api2/test_data/GetMetrics_group_by_queryid.json
index d4e86c01e2..c383b330df 100644
--- a/qan-api2/test_data/GetMetrics_group_by_queryid.json
+++ b/qan-api2/test_data/GetMetrics_group_by_queryid.json
@@ -3435,15 +3435,13 @@
},
"fingerprint": "select @@global.slow_query_log_file",
"metadata": {
- "serviceName": "server0",
- "schema": "schema29",
- "username": "user8",
+ "serviceName": "server0, server1, server2, server3, server4, server5, server6, server7, server8, server9",
+ "schema": "schema0, schema1, schema10, schema13, schema14, schema20, schema21, schema23, schema27, schema28, schema29, schema3, schema30, schema31, schema33, schema35, schema37, schema40, schema42, schema44, schema46, schema47, schema48, schema51, schema52, schema53, schema56, schema58, schema59, schema60, schema61, schema65, schema68, schema69, schema70, schema72, schema74, schema75, schema76, schema77, schema80, schema81, schema82, schema84, schema88, schema89, schema94, schema96, schema97, schema99",
+ "username": "user1, user10, user14, user16, user24, user26, user27, user28, user30, user31, user32, user33, user34, user38, user40, user41, user44, user45, user46, user49, user55, user56, user6, user60, user61, user64, user67, user69, user70, user74, user76, user79, user8, user82, user84, user85, user86, user87, user89, user90, user91, user92, user95, user96, user97, user98, user99",
"replicationSet": "replication_set1",
"cluster": "cluster1",
"serviceType": "service_type1",
- "serviceId": "service_id1",
"environment": "environment1",
- "nodeId": "node_id1",
"nodeName": "node_name1",
"nodeType": "node_type1"
}
diff --git a/qan-api2/test_data/GetMetrics_sparklines_90_points.json b/qan-api2/test_data/GetMetrics_sparklines_90_points.json
index 4b69df0d83..91cedf727d 100644
--- a/qan-api2/test_data/GetMetrics_sparklines_90_points.json
+++ b/qan-api2/test_data/GetMetrics_sparklines_90_points.json
@@ -1437,15 +1437,13 @@
},
"fingerprint": "select @@global.slow_query_log_file",
"metadata": {
- "serviceName": "server2",
- "schema": "schema81",
- "username": "user38",
+ "serviceName": "server2, server3, server4, server5, server6, server7, server8, server9",
+ "schema": "schema10, schema13, schema3, schema33, schema35, schema40, schema44, schema52, schema59, schema61, schema72, schema81, schema96",
+ "username": "user1, user26, user27, user28, user31, user38, user64, user82, user95, user96, user97, user98",
"replicationSet": "replication_set1",
"cluster": "cluster1",
"serviceType": "service_type1",
- "serviceId": "service_id1",
"environment": "environment1",
- "nodeId": "node_id1",
"nodeName": "node_name1",
"nodeType": "node_type1"
}
diff --git a/qan-api2/test_data/GetMetrics_total.json b/qan-api2/test_data/GetMetrics_total.json
index 32978b0f56..d144f24dd5 100644
--- a/qan-api2/test_data/GetMetrics_total.json
+++ b/qan-api2/test_data/GetMetrics_total.json
@@ -6698,15 +6698,13 @@
}
},
"metadata": {
- "serviceName": "server0",
- "schema": "schema12",
- "username": "user19",
+ "serviceName": "server0, server1, server2, server3, server4, server5, server6, server7, server8, server9",
+ "schema": "schema0, schema1, schema10, schema11, schema12, schema13, schema14, schema15, schema16, schema17, schema18, schema19, schema2, schema20, schema21, schema22, schema23, schema24, schema25, schema26, schema27, schema28, schema29, schema3, schema30, schema31, schema32, schema33, schema34, schema35, schema36, schema37, schema38, schema39, schema4, schema40, schema41, schema42, schema43, schema44, schema45, schema46, schema47, schema48, schema49, schema5, schema50, schema51, schema52, schema53, schema54, schema55, schema56, schema57, schema58, schema59, schema6, schema60, schema61, schema62, schema63, schema64, schema65, schema66, schema67, schema68, schema69, schema7, schema70, schema71, schema72, schema73, schema74, schema75, schema76, schema77, schema78, schema79, schema8, schema80, schema81, schema82, schema83, schema84, schema85, schema86, schema87, schema88, schema89, schema9, schema90, schema91, schema92, schema93, schema94, schema95, schema96, schema97, schema98, schema99",
+ "username": "user0, user1, user10, user11, user12, user13, user14, user15, user16, user17, user18, user19, user2, user20, user21, user22, user23, user24, user25, user26, user27, user28, user29, user3, user30, user31, user32, user33, user34, user35, user36, user37, user38, user39, user4, user40, user41, user42, user43, user44, user45, user46, user47, user48, user49, user5, user50, user51, user52, user53, user54, user55, user56, user57, user58, user59, user6, user60, user61, user62, user63, user64, user65, user66, user67, user68, user69, user7, user70, user71, user72, user73, user74, user75, user76, user77, user78, user79, user8, user80, user81, user82, user83, user84, user85, user86, user87, user88, user89, user9, user90, user91, user92, user93, user94, user95, user96, user97, user98, user99",
"replicationSet": "replication_set1",
"cluster": "cluster1",
"serviceType": "service_type1",
- "serviceId": "service_id1",
"environment": "environment1",
- "nodeId": "node_id1",
"nodeName": "node_name1",
"nodeType": "node_type1"
}
diff --git a/qan-api2/utils/interceptors/interceptors.go b/qan-api2/utils/interceptors/interceptors.go
index c5aca053fb..fa2cda3033 100644
--- a/qan-api2/utils/interceptors/interceptors.go
+++ b/qan-api2/utils/interceptors/interceptors.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -124,7 +124,7 @@ func Stream(srv interface{}, ss grpc.ServerStream, info *grpc.StreamServerInfo,
return err
}
-// check interfaces
+// check interfaces.
var (
_ grpc.UnaryServerInterceptor = Unary
_ grpc.StreamServerInterceptor = Stream
diff --git a/qan-api2/utils/logger/grpc.go b/qan-api2/utils/logger/grpc.go
index d658750634..7fa6342b83 100644
--- a/qan-api2/utils/logger/grpc.go
+++ b/qan-api2/utils/logger/grpc.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +38,7 @@ func (v *GRPC) Info(args ...interface{}) { v.Trace(args...) }
func (v *GRPC) Infoln(args ...interface{}) { v.Traceln(args...) }
func (v *GRPC) Infof(format string, args ...interface{}) { v.Tracef(format, args...) }
-// check interfaces
+// check interfaces.
var (
_ grpclog.LoggerV2 = (*GRPC)(nil)
)
diff --git a/qan-api2/utils/logger/logger.go b/qan-api2/utils/logger/logger.go
index d51b3cc4f6..5bc5b12f8e 100644
--- a/qan-api2/utils/logger/logger.go
+++ b/qan-api2/utils/logger/logger.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -23,7 +23,7 @@ import (
"github.com/sirupsen/logrus"
)
-// key is unexported to prevent collisions - it is different from any other type in other packages
+// key is unexported to prevent collisions - it is different from any other type in other packages.
var key = struct{}{}
// Get returns logrus entry for given context. Set must be called before this method is called.
diff --git a/tools/go.mod b/tools/go.mod
index 8219ee2346..a249cc15de 100644
--- a/tools/go.mod
+++ b/tools/go.mod
@@ -1,28 +1,28 @@
module github.com/percona/pmm/tools
-go 1.20
+go 1.21
replace github.com/go-openapi/spec => github.com/Percona-Lab/spec v0.20.5-percona
require (
github.com/BurntSushi/go-sumtype v0.0.0-20190304192233-fcb4a6205bdc
github.com/Percona-Lab/swagger-order v0.0.0-20191002141859-166b3973d026
- github.com/apache/skywalking-eyes v0.4.0
- github.com/bufbuild/buf v1.23.0
- github.com/daixiang0/gci v0.10.1
- github.com/envoyproxy/protoc-gen-validate v1.0.1
+ github.com/apache/skywalking-eyes v0.5.0
+ github.com/bufbuild/buf v1.26.1
+ github.com/daixiang0/gci v0.11.0
+ github.com/envoyproxy/protoc-gen-validate v1.0.2
github.com/go-delve/delve v1.21.0
github.com/go-openapi/runtime v0.25.0
github.com/go-openapi/spec v0.20.4
github.com/go-swagger/go-swagger v0.29.0
- github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0
+ github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0
github.com/jstemmer/go-junit-report v1.0.0
- github.com/quasilyte/go-consistent v0.0.0-20200404105227-766526bf1e96
- github.com/reviewdog/reviewdog v0.14.1
+ github.com/quasilyte/go-consistent v0.6.0
+ github.com/reviewdog/reviewdog v0.15.0
github.com/vburenin/ifacemaker v1.2.1
- github.com/vektra/mockery/v2 v2.30.16
- golang.org/x/perf v0.0.0-20211012211434-03971e389cd3
- golang.org/x/tools v0.10.0
+ github.com/vektra/mockery/v2 v2.33.0
+ golang.org/x/perf v0.0.0-20230717203022-1ba3a21238c9
+ golang.org/x/tools v0.13.0
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0
google.golang.org/protobuf v1.31.0
gopkg.in/reform.v1 v1.5.1
@@ -30,41 +30,49 @@ require (
)
require (
- cloud.google.com/go v0.110.0 // indirect
- cloud.google.com/go/compute v1.19.1 // indirect
+ cloud.google.com/go v0.110.7 // indirect
+ cloud.google.com/go/compute v1.23.0 // indirect
cloud.google.com/go/compute/metadata v0.2.3 // indirect
- cloud.google.com/go/datastore v1.11.0 // indirect
+ cloud.google.com/go/datastore v1.14.0 // indirect
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 // indirect
github.com/Masterminds/goutils v1.1.1 // indirect
- github.com/Masterminds/semver/v3 v3.1.1 // indirect
- github.com/Masterminds/sprig/v3 v3.2.2 // indirect
+ github.com/Masterminds/semver/v3 v3.2.0 // indirect
+ github.com/Masterminds/sprig/v3 v3.2.3 // indirect
github.com/Microsoft/go-winio v0.6.1 // indirect
+ github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect
+ github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794 // indirect
+ github.com/acomagu/bufpipe v1.0.4 // indirect
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 // indirect
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 // indirect
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d // indirect
github.com/bmatcuk/doublestar/v2 v2.0.4 // indirect
- github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 // indirect
- github.com/bufbuild/connect-go v1.8.0 // indirect
- github.com/bufbuild/connect-opentelemetry-go v0.3.0 // indirect
- github.com/bufbuild/protocompile v0.5.1 // indirect
+ github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 // indirect
+ github.com/bufbuild/connect-go v1.9.0 // indirect
+ github.com/bufbuild/connect-opentelemetry-go v0.4.0 // indirect
+ github.com/bufbuild/protocompile v0.6.0 // indirect
github.com/chigopher/pathlib v0.15.0 // indirect
github.com/cilium/ebpf v0.7.0 // indirect
+ github.com/cloudflare/circl v1.3.3 // indirect
github.com/containerd/stargz-snapshotter/estargz v0.14.3 // indirect
github.com/cosiner/argv v0.1.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.2 // indirect
github.com/denisenkom/go-mssqldb v0.9.0 // indirect
github.com/derekparker/trie v0.0.0-20221213183930-4c74548207f4 // indirect
- github.com/docker/cli v24.0.2+incompatible // indirect
+ github.com/docker/cli v24.0.4+incompatible // indirect
github.com/docker/distribution v2.8.2+incompatible // indirect
- github.com/docker/docker v24.0.2+incompatible // indirect
- github.com/docker/docker-credential-helpers v0.7.0 // indirect
+ github.com/docker/docker v24.0.4+incompatible // indirect
+ github.com/docker/docker-credential-helpers v0.8.0 // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.5.0 // indirect
+ github.com/emirpasic/gods v1.18.1 // indirect
github.com/felixge/fgprof v0.9.3 // indirect
- github.com/felixge/httpsnoop v1.0.2 // indirect
+ github.com/felixge/httpsnoop v1.0.3 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
- github.com/go-chi/chi/v5 v5.0.8 // indirect
+ github.com/go-chi/chi/v5 v5.0.10 // indirect
github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d // indirect
+ github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect
+ github.com/go-git/go-billy/v5 v5.4.1 // indirect
+ github.com/go-git/go-git/v5 v5.8.0 // indirect
github.com/go-logr/logr v1.2.4 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-openapi/analysis v0.21.3 // indirect
@@ -86,7 +94,7 @@ require (
github.com/gofrs/uuid v4.4.0+incompatible // indirect
github.com/gofrs/uuid/v5 v5.0.0 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
- github.com/golang-jwt/jwt/v4 v4.1.0 // indirect
+ github.com/golang-jwt/jwt/v4 v4.5.0 // indirect
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe // indirect
github.com/golang/glog v1.1.0 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
@@ -95,33 +103,36 @@ require (
github.com/google/go-containerregistry v0.15.2 // indirect
github.com/google/go-dap v0.9.1 // indirect
github.com/google/go-github/v33 v33.0.0 // indirect
- github.com/google/go-github/v39 v39.2.0 // indirect
- github.com/google/go-github/v41 v41.0.0 // indirect
+ github.com/google/go-github/v53 v53.2.0 // indirect
+ github.com/google/go-github/v55 v55.0.0 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/google/licensecheck v0.3.1 // indirect
- github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 // indirect
+ github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 // indirect
+ github.com/google/s2a-go v0.1.4 // indirect
github.com/google/uuid v1.3.0 // indirect
- github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect
- github.com/googleapis/gax-go/v2 v2.7.1 // indirect
+ github.com/googleapis/enterprise-certificate-proxy v0.2.5 // indirect
+ github.com/googleapis/gax-go/v2 v2.12.0 // indirect
github.com/gorilla/handlers v1.5.1 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
- github.com/hashicorp/go-retryablehttp v0.7.0 // indirect
+ github.com/hashicorp/go-retryablehttp v0.7.2 // indirect
github.com/hashicorp/golang-lru v0.5.4 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/haya14busa/go-actions-toolkit v0.0.0-20200105081403-ca0307860f01 // indirect
github.com/hexops/gotextdiff v1.0.3 // indirect
- github.com/huandu/xstrings v1.3.1 // indirect
+ github.com/huandu/xstrings v1.4.0 // indirect
github.com/iancoleman/orderedmap v0.2.0 // indirect
github.com/iancoleman/strcase v0.2.0 // indirect
- github.com/imdario/mergo v0.3.12 // indirect
+ github.com/imdario/mergo v0.3.16 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/jackc/pgx v3.6.2+incompatible // indirect
+ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 // indirect
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 // indirect
github.com/jessevdk/go-flags v1.5.0 // indirect
github.com/jinzhu/copier v0.3.5 // indirect
github.com/josharian/intern v1.0.0 // indirect
+ github.com/kevinburke/ssh_config v1.2.0 // indirect
github.com/kisielk/gotool v1.0.0 // indirect
- github.com/klauspost/compress v1.16.6 // indirect
+ github.com/klauspost/compress v1.16.7 // indirect
github.com/klauspost/pgzip v1.2.6 // indirect
github.com/kr/pretty v0.3.1 // indirect
github.com/kr/text v0.2.0 // indirect
@@ -133,31 +144,34 @@ require (
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-runewidth v0.0.13 // indirect
github.com/mattn/go-shellwords v1.0.12 // indirect
- github.com/mattn/go-sqlite3 v1.14.5 // indirect
- github.com/mitchellh/copystructure v1.0.0 // indirect
+ github.com/mattn/go-sqlite3 v1.14.6 // indirect
+ github.com/mitchellh/copystructure v1.2.0 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
- github.com/mitchellh/reflectwalk v1.0.1 // indirect
+ github.com/mitchellh/reflectwalk v1.0.2 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/morikuni/aec v1.0.0 // indirect
github.com/oklog/ulid v1.3.1 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
- github.com/opencontainers/image-spec v1.1.0-rc3 // indirect
+ github.com/opencontainers/image-spec v1.1.0-rc4 // indirect
github.com/opentracing/opentracing-go v1.2.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
+ github.com/pjbgf/sha1cd v0.3.0 // indirect
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pkg/profile v1.7.0 // indirect
github.com/reva2/bitbucket-insights-api v1.0.0 // indirect
- github.com/reviewdog/errorformat v0.0.0-20220309155058-b075c45b6d9a // indirect
+ github.com/reviewdog/errorformat v0.0.0-20230810075619-82e5d4ad20d2 // indirect
github.com/reviewdog/go-bitbucket v0.0.0-20201024094602-708c3f6a7de0 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/rogpeppe/go-internal v1.10.0 // indirect
github.com/rs/cors v1.9.0 // indirect
github.com/rs/zerolog v1.29.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
- github.com/shopspring/decimal v1.2.0 // indirect
+ github.com/sergi/go-diff v1.3.1 // indirect
+ github.com/shopspring/decimal v1.3.1 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
+ github.com/skeema/knownhosts v1.2.0 // indirect
github.com/spf13/afero v1.9.3 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/cobra v1.7.0 // indirect
@@ -165,11 +179,12 @@ require (
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.15.0 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
- github.com/tetratelabs/wazero v1.2.1 // indirect
+ github.com/tetratelabs/wazero v1.3.1 // indirect
github.com/toqueteos/webbrowser v1.2.0 // indirect
github.com/vbatts/tar-split v0.11.3 // indirect
- github.com/vvakame/sdlog v0.0.0-20200409072131-7c0d359efddc // indirect
- github.com/xanzy/go-gitlab v0.63.0 // indirect
+ github.com/vvakame/sdlog v1.2.0 // indirect
+ github.com/xanzy/go-gitlab v0.91.1 // indirect
+ github.com/xanzy/ssh-agent v0.3.3 // indirect
go.mongodb.org/mongo-driver v1.9.0 // indirect
go.opencensus.io v0.24.0 // indirect
go.opentelemetry.io/otel v1.16.0 // indirect
@@ -181,26 +196,27 @@ require (
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.24.0 // indirect
golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 // indirect
- golang.org/x/build v0.0.0-20200616162219-07bebbe343e9 // indirect
- golang.org/x/crypto v0.10.0 // indirect
+ golang.org/x/build v0.0.0-20230905185615-7f65e2bc812a // indirect
+ golang.org/x/crypto v0.13.0 // indirect
golang.org/x/lint v0.0.0-20210508222113-6edffad5e616 // indirect
- golang.org/x/mod v0.11.0 // indirect
- golang.org/x/net v0.11.0 // indirect
- golang.org/x/oauth2 v0.8.0 // indirect
+ golang.org/x/mod v0.12.0 // indirect
+ golang.org/x/net v0.15.0 // indirect
+ golang.org/x/oauth2 v0.12.0 // indirect
golang.org/x/sync v0.3.0 // indirect
- golang.org/x/sys v0.9.0 // indirect
- golang.org/x/term v0.9.0 // indirect
- golang.org/x/text v0.10.0 // indirect
- golang.org/x/time v0.1.0 // indirect
+ golang.org/x/sys v0.12.0 // indirect
+ golang.org/x/term v0.12.0 // indirect
+ golang.org/x/text v0.13.0 // indirect
+ golang.org/x/time v0.3.0 // indirect
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect
- google.golang.org/api v0.114.0 // indirect
- google.golang.org/appengine v1.6.7 // indirect
- google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e // indirect
- google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc // indirect
- google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc // indirect
- google.golang.org/grpc v1.55.0 // indirect
+ google.golang.org/api v0.128.0 // indirect
+ google.golang.org/appengine v1.6.8-0.20221117013220-504804fb50de // indirect
+ google.golang.org/genproto v0.0.0-20230821184602-ccc8af3d0e93 // indirect
+ google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d // indirect
+ google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
+ google.golang.org/grpc v1.58.0 // indirect
gopkg.in/alecthomas/kingpin.v2 v2.2.6 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
+ gopkg.in/warnings.v0 v0.1.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
diff --git a/tools/go.sum b/tools/go.sum
index 4cffd9135b..ea9d3bd983 100644
--- a/tools/go.sum
+++ b/tools/go.sum
@@ -18,24 +18,24 @@ cloud.google.com/go v0.65.0/go.mod h1:O5N8zS7uWy9vkA9vayVHs65eM1ubvY4h553ofrNHOb
cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKPI=
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
cloud.google.com/go v0.75.0/go.mod h1:VGuuCn7PG0dwsd5XPVm2Mm3wlh3EL55/79EKB6hlPTY=
-cloud.google.com/go v0.110.0 h1:Zc8gqp3+a9/Eyph2KDmcGaPtbKRIoqq4YTlL4NMD0Ys=
-cloud.google.com/go v0.110.0/go.mod h1:SJnCLqQ0FCFGSZMUNUf84MV3Aia54kn7pi8st7tMzaY=
+cloud.google.com/go v0.110.7 h1:rJyC7nWRg2jWGZ4wSJ5nY65GTdYJkg0cd/uXb+ACI6o=
+cloud.google.com/go v0.110.7/go.mod h1:+EYjdK8e5RME/VY/qLCAtuyALQ9q67dvuum8i+H5xsI=
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/compute v1.19.1 h1:am86mquDUgjGNWxiGn+5PGLbmgiWXlE/yNWpIpNvuXY=
-cloud.google.com/go/compute v1.19.1/go.mod h1:6ylj3a05WF8leseCdIf77NK0g1ey+nj5IKd5/kvShxE=
+cloud.google.com/go/compute v1.23.0 h1:tP41Zoavr8ptEqaW6j+LQOnyBBhO7OkOMAGrgLopTwY=
+cloud.google.com/go/compute v1.23.0/go.mod h1:4tCnrn48xsqlwSAiLf1HXMQk8CONslYbdiEZc9FEIbM=
+cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k=
cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY=
cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA=
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/datastore v1.11.0 h1:iF6I/HaLs3Ado8uRKMvZRvF/ZLkWaWE9i8AiHzbC774=
-cloud.google.com/go/datastore v1.11.0/go.mod h1:TvGxBIHCS50u8jzG+AW/ppf87v1of8nwzFNgEZU1D3c=
+cloud.google.com/go/datastore v1.14.0 h1:Mq0ApTRdLW3/dyiw+DkjTk0+iGIUvkbzaC8sfPwWTH4=
+cloud.google.com/go/datastore v1.14.0/go.mod h1:GAeStMBIt9bPS7jMJA85kgkpsMkvseWWXiaHya9Jes8=
cloud.google.com/go/firestore v1.1.0/go.mod h1:ulACoGHTpvq5r8rxGJ4ddJZBZqakUQqClKRT5SZwBmk=
-cloud.google.com/go/longrunning v0.4.1 h1:v+yFJOfKC3yZdY6ZUI933pIYdhyhV8S3NpWrXWmg7jM=
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=
@@ -47,6 +47,7 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
cloud.google.com/go/storage v1.14.0/go.mod h1:GrKmX003DSIwi9o29oFT7YDnHYwZoctc3fOKtUw0Xmo=
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
+gioui.org v0.0.0-20210308172011-57750fc8a0a6/go.mod h1:RSH6KIUZ0p2xy5zHDxgAM4zumjgTw83q2ge/PI+yyw8=
github.com/AlekSi/pointer v1.1.0 h1:SSDMPcXD9jSl8FPy9cRzoRaMJtm9g9ggGTxecRUbQoI=
github.com/AlekSi/pointer v1.1.0/go.mod h1:y7BvfRI3wXPWKXEBhU71nbnIEEZX0QTSB2Bj48UJIZE=
github.com/Azure/go-ansiterm v0.0.0-20230124172434-306776ec8161 h1:L/gRVlceqvL25UVaW/CKtUDjefjrs0SPonmDGUVOYP0=
@@ -59,21 +60,29 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym
github.com/GoogleCloudPlatform/cloudsql-proxy v0.0.0-20190129172621-c8b1d7a94ddf/go.mod h1:aJ4qN3TfrelA6NZ6AXsXRfmEVaYin3EDbSPJrKS8OXo=
github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
-github.com/Masterminds/semver/v3 v3.1.1 h1:hLg3sBzpNErnxhQtUy/mmLR2I9foDujNK030IGemrRc=
-github.com/Masterminds/semver/v3 v3.1.1/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
-github.com/Masterminds/sprig/v3 v3.2.2 h1:17jRggJu518dr3QaafizSXOjKYp94wKfABxUmyxvxX8=
-github.com/Masterminds/sprig/v3 v3.2.2/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFPhxNuwnnxkKlk=
+github.com/Masterminds/semver/v3 v3.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
+github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=
+github.com/Masterminds/sprig/v3 v3.2.3 h1:eL2fZNezLomi0uOLqjQoN6BfsDD+fyLtgbJMAj9n6YA=
+github.com/Masterminds/sprig/v3 v3.2.3/go.mod h1:rXcFaZ2zZbLRJv/xSysmlgIM1u11eBaRMhvYXJNkGuM=
+github.com/Microsoft/go-winio v0.5.2/go.mod h1:WpS1mjBmmwHBEWmogvA2mj8546UReBk4v8QkMxJ6pZY=
github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow=
github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM=
-github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
github.com/Percona-Lab/spec v0.20.5-percona h1:ViCJVq52QIZxpP8/Nv4/nIed+WnqUirNjPtXvHhset4=
github.com/Percona-Lab/spec v0.20.5-percona/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA=
github.com/Percona-Lab/swagger-order v0.0.0-20191002141859-166b3973d026 h1:jvuxsQEuFpoSVw9HCP4kSF52BXYzTvB7CA3eryQXaRc=
github.com/Percona-Lab/swagger-order v0.0.0-20191002141859-166b3973d026/go.mod h1:rTCUGM0dF3N6kw5DdoxLDWe7FL49OxY13Y0Ev1jS/BQ=
+github.com/ProtonMail/go-crypto v0.0.0-20230217124315-7d5c6f04bbb8/go.mod h1:I0gYDMZ6Z5GRU7l58bNFSkPTFN6Yl12dsUlAZ8xy98g=
+github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs=
+github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0=
github.com/PuerkitoBio/goquery v1.5.1/go.mod h1:GsLWisAFVj4WgDibEWF4pvYnkVQBpKBKeU+7zCJoLcc=
github.com/aclements/go-gg v0.0.0-20170118225347-6dbb4e4fefb0/go.mod h1:55qNq4vcpkIuHowELi5C8e+1yUHtoLoOUR9QU5j7Tes=
-github.com/aclements/go-moremath v0.0.0-20161014184102-0ff62e0875ff/go.mod h1:idZL3yvz4kzx1dsBOAC+oYv6L92P1oFEhUXUB1A/lwQ=
+github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794 h1:xlwdaKcTNVW4PtpQb8aKA4Pjy0CdJHEqvFbAnvR5m2g=
+github.com/aclements/go-moremath v0.0.0-20210112150236-f10218a38794/go.mod h1:7e+I0LQFUI9AXWxOfsQROs9xPhoJtbsyWcjJqDd4KPY=
+github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ=
+github.com/acomagu/bufpipe v1.0.4/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
+github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
+github.com/ajstarks/svgo v0.0.0-20210923152817-c3b6e2f0c527/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw=
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=
@@ -81,38 +90,46 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF
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/andybalholm/cascadia v1.1.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
-github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
-github.com/apache/skywalking-eyes v0.4.0 h1:O13kdRU6FCEZevfD01mdhTgCZLLfPZIQ0GXZrLl7FpQ=
-github.com/apache/skywalking-eyes v0.4.0/go.mod h1:WblDbBgOLsLN0FJEBa9xj6PhuUA/J6spKYVTG4/F8Ls=
+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be h1:9AeTilPcZAjCFIImctFaOjnTIavg87rW78vTPkQqLI8=
+github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be/go.mod h1:ySMOLuWl6zY27l47sB3qLNK6tF2fkHG55UZxx8oIVo4=
+github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
+github.com/apache/skywalking-eyes v0.5.0 h1:X41jAhmnJazHuR5mOGt1nZA7mFaAluf9mvB1JBzr5xI=
+github.com/apache/skywalking-eyes v0.5.0/go.mod h1:rwVEbfh8GovISedSOc7nHGrcnkQ7sfTc31iYU5hSpEE=
github.com/armon/circbuf v0.0.0-20150827004946-bbbad097214e/go.mod h1:3U/XgcO3hCbHZ8TKRvWD2dDTCfh9M9ya+I9JpbB7O8o=
github.com/armon/go-metrics v0.0.0-20180917152333-f0300d1749da/go.mod h1:Q73ZrmVTwzkszR9V5SSuryQ31EELlFMUz1kKyl939pY=
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
+github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
+github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d h1:Byv0BzEl3/e6D5CLfI0j/7hiIEtvGVFPCZ7Ei2oq8iQ=
github.com/asaskevich/govalidator v0.0.0-20210307081110-f21760c49a8d/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw=
-github.com/aws/aws-sdk-go v1.30.15/go.mod h1:5zCpMtNQVjRREroY7sYe8lOMRSxkhG6MZveU8YkpAk0=
github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o=
+github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84=
github.com/bmatcuk/doublestar/v2 v2.0.4 h1:6I6oUiT/sU27eE2OFcWqBhL1SwjyvQuOssxT4a1yidI=
github.com/bmatcuk/doublestar/v2 v2.0.4/go.mod h1:QMmcs3H2AUQICWhfzLXz+IYln8lRQmTZRptLie8RgRw=
-github.com/bradfitz/go-smtpd v0.0.0-20170404230938-deb6d6237625/go.mod h1:HYsPBTaaSFSlLx/70C2HPIMNZpVV8+vt/A+FMnYP11g=
-github.com/bradleyfalzon/ghinstallation/v2 v2.0.4 h1:tXKVfhE7FcSkhkv0UwkLvPDeZ4kz6OXd0PKPlFqf81M=
-github.com/bradleyfalzon/ghinstallation/v2 v2.0.4/go.mod h1:B40qPqJxWE0jDZgOR1JmaMy+4AY1eBP+IByOvqyAKp0=
+github.com/boombuler/barcode v1.0.0/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
+github.com/boombuler/barcode v1.0.1/go.mod h1:paBWMcWSl3LHKBqUq+rly7CNSldXjb2rDl3JlRe0mD8=
+github.com/bradleyfalzon/ghinstallation/v2 v2.6.0 h1:IRY7Xy588KylkoycsUhFpW7cdGpy5Y5BPsz4IfuJtGk=
+github.com/bradleyfalzon/ghinstallation/v2 v2.6.0/go.mod h1:oQ3etOwN3TRH4EwgW5/7MxSVMGlMlzG/O8TU7eYdoSk=
github.com/brianvoe/gofakeit v3.18.0+incompatible h1:wDOmHc9DLG4nRjUVVaxA+CEglKOW72Y5+4WNxUIkjM8=
github.com/brianvoe/gofakeit v3.18.0+incompatible/go.mod h1:kfwdRA90vvNhPutZWfH7WPaDzUjz+CZFqG+rPkOjGOc=
-github.com/bufbuild/buf v1.23.0 h1:QD6xCygtCVhN6qsQ4TtE2xGRK86xGkjI9lNHJ5jaj+M=
-github.com/bufbuild/buf v1.23.0/go.mod h1:ERFRzJiIjAOzUSJ3vz1zoI7XfxlBnCwZEyL+NJm4pko=
-github.com/bufbuild/connect-go v1.8.0 h1:srluNkFkZBfSfg9Qb6DrO+5nMaxix//h2ctrHZhMGKc=
-github.com/bufbuild/connect-go v1.8.0/go.mod h1:GmMJYR6orFqD0Y6ZgX8pwQ8j9baizDrIQMm1/a6LnHk=
-github.com/bufbuild/connect-opentelemetry-go v0.3.0 h1:AuZi3asTDKmjGtd2aqpyP4p5QvBFG/YEaHopViLatnk=
-github.com/bufbuild/connect-opentelemetry-go v0.3.0/go.mod h1:r1ppyTtu1EWeRodk4Q/JbyQhIWtO7eR3GoRDzjeEcNU=
-github.com/bufbuild/protocompile v0.5.1 h1:mixz5lJX4Hiz4FpqFREJHIXLfaLBntfaJv1h+/jS+Qg=
-github.com/bufbuild/protocompile v0.5.1/go.mod h1:G5iLmavmF4NsYtpZFvE3B/zFch2GIY8+wjsYLR/lc40=
+github.com/bufbuild/buf v1.26.1 h1:+GdU4z2paCmDclnjLv7MqnVi3AGviImlIKhG0MHH9FA=
+github.com/bufbuild/buf v1.26.1/go.mod h1:UMPncXMWgrmIM+0QpwTEwjNr2SA0z2YIVZZsmNflvB4=
+github.com/bufbuild/connect-go v1.9.0 h1:JIgAeNuFpo+SUPfU19Yt5TcWlznsN5Bv10/gI/6Pjoc=
+github.com/bufbuild/connect-go v1.9.0/go.mod h1:CAIePUgkDR5pAFaylSMtNK45ANQjp9JvpluG20rhpV8=
+github.com/bufbuild/connect-opentelemetry-go v0.4.0 h1:6JAn10SNqlQ/URhvRNGrIlczKw1wEXknBUUtmWqOiak=
+github.com/bufbuild/connect-opentelemetry-go v0.4.0/go.mod h1:nwPXYoDOoc2DGyKE/6pT1Q9MPSi2Et2e6BieMD0l6WU=
+github.com/bufbuild/protocompile v0.6.0 h1:Uu7WiSQ6Yj9DbkdnOe7U4mNKp58y9WDMKDn28/ZlunY=
+github.com/bufbuild/protocompile v0.6.0/go.mod h1:YNP35qEYoYGme7QMtz5SBCoN4kL4g12jTtjuzRNdjpE=
+github.com/bwesterb/go-ristretto v1.2.0/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
+github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
+github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chigopher/pathlib v0.15.0 h1:1pg96WL3iC1/YyWV4UJSl3E0GBf4B+h5amBtsbAAieY=
github.com/chigopher/pathlib v0.15.0/go.mod h1:3+YPPV21mU9vyw8Mjp+F33CyCfE6iOzinpiqBcccv7I=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
@@ -121,9 +138,16 @@ github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMn
github.com/cilium/ebpf v0.7.0 h1:1k/q3ATgxSXRdrmPfH8d7YK0GfqVsEKZAX9dQZvs56k=
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
+github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
+github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs=
+github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA=
github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGXZJjfX53e64911xZQV5JYwmTeXPW+k8Sc=
github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
+github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XPnfI9Z40ddWsdw2W/uZgQLFXToKeRcDiI=
+github.com/cncf/xds/go v0.0.0-20210805033703-aa0b78936158/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
+github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs=
github.com/cockroachdb/apd v1.1.0 h1:3LFP3629v+1aKXU5Q37mxmRxX/pIu1nijXydLShEq5I=
github.com/cockroachdb/apd v1.1.0/go.mod h1:8Sl8LxpKi29FqWXR16WEFZRNSz3SoPzUzeMeY4+DwBQ=
github.com/containerd/stargz-snapshotter/estargz v0.14.3 h1:OqlDCK3ZVUO6C3B/5FSkDwbkEETK84kQgEeFwDC+62k=
@@ -131,20 +155,19 @@ github.com/containerd/stargz-snapshotter/estargz v0.14.3/go.mod h1:KY//uOCIkSuNA
github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk=
github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE=
github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk=
-github.com/coreos/go-systemd v0.0.0-20181012123002-c6f51f82210d/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
github.com/coreos/go-systemd/v22 v22.3.3-0.20220203105225-a9a7ef127534/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA=
github.com/cosiner/argv v0.1.0 h1:BVDiEL32lwHukgJKP87btEPenzrrHUjajs/8yzaqcXg=
github.com/cosiner/argv v0.1.0/go.mod h1:EusR6TucWKX+zFgtdUsKT2Cvg45K5rtpCcWz4hK06d8=
github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
-github.com/cpuguy83/go-md2man/v2 v2.0.1/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/cpuguy83/go-md2man/v2 v2.0.2 h1:p1EgwI/C7NhT0JmVkwCD2ZBK8j4aeHQX2pMHHBfMQ6w=
github.com/cpuguy83/go-md2man/v2 v2.0.2/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
-github.com/daixiang0/gci v0.10.1 h1:eheNA3ljF6SxnPD/vE4lCBusVHmV3Rs3dkKvFrJ7MR0=
-github.com/daixiang0/gci v0.10.1/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI=
+github.com/creack/pty v1.1.18/go.mod h1:MOBLtS5ELjhRRrroQr9kyvTxUAFNvYEK993ew/Vr4O4=
+github.com/daixiang0/gci v0.11.0 h1:XeQbFKkCRxvVyn06EOuNY6LPGBLVuB/W130c8FrnX6A=
+github.com/daixiang0/gci v0.11.0/go.mod h1:xtHP9N7AHdNvtRNfcx9gwTDfw7FRJx4bZUsiEfiNNAI=
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=
@@ -154,51 +177,75 @@ github.com/derekparker/trie v0.0.0-20221213183930-4c74548207f4 h1:atN94qKNhLpy+9
github.com/derekparker/trie v0.0.0-20221213183930-4c74548207f4/go.mod h1:C7Es+DLenIpPc9J6IYw4jrK0h7S9bKj4DNl8+KxGEXU=
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no=
-github.com/docker/cli v24.0.2+incompatible h1:QdqR7znue1mtkXIJ+ruQMGQhpw2JzMJLRXp6zpzF6tM=
-github.com/docker/cli v24.0.2+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
+github.com/docker/cli v24.0.4+incompatible h1:Y3bYF9ekNTm2VFz5U/0BlMdJy73D+Y1iAAZ8l63Ydzw=
+github.com/docker/cli v24.0.4+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/distribution v2.8.2+incompatible h1:T3de5rq0dB1j30rp0sA2rER+m322EBzniBPB6ZIzuh8=
github.com/docker/distribution v2.8.2+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
-github.com/docker/docker v24.0.2+incompatible h1:eATx+oLz9WdNVkQrr0qjQ8HvRJ4bOOxfzEo8R+dA3cg=
-github.com/docker/docker v24.0.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
-github.com/docker/docker-credential-helpers v0.7.0 h1:xtCHsjxogADNZcdv1pKUHXryefjlVRqWqIhk/uXJp0A=
-github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNkFR1R1V12OJRRO5lzt2D1b5X0=
+github.com/docker/docker v24.0.4+incompatible h1:s/LVDftw9hjblvqIeTiGYXBCD95nOEEl7qRsRrIOuQI=
+github.com/docker/docker v24.0.4+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
+github.com/docker/docker-credential-helpers v0.8.0 h1:YQFtbBQb4VrpoPxhFuzEBPQ9E16qz5SpHLS+uswaCp8=
+github.com/docker/docker-credential-helpers v0.8.0/go.mod h1:UGFXcuoQ5TxPiB54nHOZ32AWRqQdECoh/Mg0AlEYb40=
github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4=
github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819 h1:RIB4cRk+lBqKK3Oy0r2gRX4ui7tuhiZq2SuTtTCi0/0=
+github.com/elazarl/goproxy v0.0.0-20221015165544-a0805db90819/go.mod h1:Ro8st/ElPeALwNFlcTpWmkr6IoMFfkjXAvTHpevnDsM=
+github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc=
+github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ=
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/go-control-plane v0.9.7/go.mod h1:cwu0lG7PUMfa9snN8LXBig5ynNVH9qI8YYLbd1fK2po=
github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk=
+github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go.mod h1:AFq3mo9L8Lqqiid3OhADV3RfLJnjiw63cSpi+fDTRC0=
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
-github.com/envoyproxy/protoc-gen-validate v1.0.1 h1:kt9FtLiooDc0vbwTLhdg3dyNX1K9Qwa1EK9LcD4jVUQ=
-github.com/envoyproxy/protoc-gen-validate v1.0.1/go.mod h1:0vj8bNkYbSTNS2PIyH87KZaeN4x9zpL9Qt8fQC7d+vs=
+github.com/envoyproxy/protoc-gen-validate v1.0.2 h1:QkIBuU5k+x7/QXPvPPnWXWlCdaBFApVqftFV6k087DA=
+github.com/envoyproxy/protoc-gen-validate v1.0.2/go.mod h1:GpiZQP3dDbg4JouG/NNS7QWXpgx6x8QiMKdmN72jogE=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w=
+github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk=
github.com/felixge/fgprof v0.9.3 h1:VvyZxILNuCiUCSXtPtYmmtGvb65nqXh2QFWc0Wpf2/g=
github.com/felixge/fgprof v0.9.3/go.mod h1:RdbpDgzqYVh/T9fPELJyV7EYJuHB55UTEULNun8eiPw=
github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
-github.com/felixge/httpsnoop v1.0.2 h1:+nS9g82KMXccJ/wp0zyRW9ZBHFETmMGtkk+2CTTrW4o=
-github.com/felixge/httpsnoop v1.0.2/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
-github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
+github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk=
+github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U=
+github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
+github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY=
+github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
github.com/fsnotify/fsnotify v1.6.0 h1:n+5WquG0fcWoWp6xPWfHdbskMCQaFnG6PfBrh1Ky4HY=
github.com/fsnotify/fsnotify v1.6.0/go.mod h1:sl3t1tCWJFWoRz9R8WJCbQihKKwmorjAbSClcnxKAGw=
github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
-github.com/gliderlabs/ssh v0.1.1/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
-github.com/go-chi/chi/v5 v5.0.8 h1:lD+NLqFcAi1ovnVZpsnObHGW4xb4J8lNmoYVfECH1Y0=
-github.com/go-chi/chi/v5 v5.0.8/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
+github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
+github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
+github.com/go-chi/chi/v5 v5.0.10 h1:rLz5avzKpjqxrYwXNfmjkrYYXOyLJd37pz53UFHC6vk=
+github.com/go-chi/chi/v5 v5.0.10/go.mod h1:DslCQbL2OYiznFReuXYUmQ2hGd1aDpCnlMNITLSKoi8=
github.com/go-delve/delve v1.21.0 h1:npcc8TZhdVxaMSJon+zqcE3bXM/ck8SSOOWw/id13jI=
github.com/go-delve/delve v1.21.0/go.mod h1:U+OAdfhewudkHsVs/AwhfpSBu7t/NgIXH3+my4T5q78=
github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d h1:pxjSLshkZJGLVm0wv20f/H0oTWiq/egkoJQ2ja6LEvo=
github.com/go-delve/liner v1.2.3-0.20220127212407-d32d89dd2a5d/go.mod h1:biJCRbqp51wS+I92HMqn5H8/A0PAhxn2vyOT+JqhiGI=
+github.com/go-fonts/dejavu v0.1.0/go.mod h1:4Wt4I4OU2Nq9asgDCteaAaWZOV24E+0/Pwo0gppep4g=
+github.com/go-fonts/latin-modern v0.2.0/go.mod h1:rQVLdDMK+mK1xscDwsqM5J8U2jrRa3T0ecnM9pNujks=
+github.com/go-fonts/liberation v0.1.1/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
+github.com/go-fonts/liberation v0.2.0/go.mod h1:K6qoJYypsmfVjWg8KOVDQhLc8UDgIK2HYqyqAO9z7GY=
+github.com/go-fonts/stix v0.1.0/go.mod h1:w/c1f0ldAUlJmLBvlbkvVXLAD+tAMqobIIQpmnUIzUY=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI=
+github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376/go.mod h1:an3vInlBmSxCcxctByoQdvwPiA7DTK7jaaFDBTtu0ic=
+github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
+github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f h1:Pz0DHeFij3XFhoBRGUDPzSJ+w2UcK5/0JvF8DRI58r8=
+github.com/go-git/go-git-fixtures/v4 v4.3.2-0.20230305113008-0c11038e723f/go.mod h1:8LHG1a3SRW71ettAD/jW13h8c6AqjVSeL11RAdgaqpo=
+github.com/go-git/go-git/v5 v5.8.0 h1:Rc543s6Tyq+YcyPwZRvU4jzZGM8rB/wWu94TnTIYALQ=
+github.com/go-git/go-git/v5 v5.8.0/go.mod h1:coJHKEOk5kUClpsNlXrUvPrDxY3w3gjHvhcZd8Fodw8=
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-latex/latex v0.0.0-20210118124228-b3d85cf34e07/go.mod h1:CO1AlKB2CSIqUrmQPqA0gdRIlnLEY0gK5JGjh37zN5U=
+github.com/go-latex/latex v0.0.0-20210823091927-c0d11ff05a81/go.mod h1:SX0U8uGpxhq9o2S/CELCSUxEWWAuoCUcVCQWv7G2OCk=
github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE=
github.com/go-logfmt/logfmt v0.4.0/go.mod h1:3RMwSq7FuexP4Kalkev3ejPJsZTpXXBr9+V4qmtdjCk=
github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A=
@@ -234,6 +281,7 @@ github.com/go-openapi/swag v0.21.1 h1:wm0rhTb5z7qpJRHBdPOMuY4QjVUMbF6/kwoYeRAOrK
github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ=
github.com/go-openapi/validate v0.21.0 h1:+Wqk39yKOhfpLqNLEC0/eViCkzM5FVXVqrvt526+wcI=
github.com/go-openapi/validate v0.21.0/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg=
+github.com/go-pdf/fpdf v0.5.0/go.mod h1:HzcnA+A23uwogo0tp9yU+l3V+KXhiESpt1PMayhOh5M=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
@@ -243,20 +291,18 @@ github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP
github.com/go-swagger/go-swagger v0.29.0 h1:z3YoZtLvS1Y8TE/PCat1VypcZxM0IgKLt0NvZxQyNl8=
github.com/go-swagger/go-swagger v0.29.0/go.mod h1:Z4GJzI+bHKKkGB2Ji1rawpi3/ldXX8CkzGIa9HAC5EE=
github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013 h1:l9rI6sNaZgNC0LnF3MiE+qTmyBA/tZAg1rtyrGbUMK0=
+github.com/go-swagger/scan-repo-boundary v0.0.0-20180623220736-973b3573c013/go.mod h1:b65mBPzqzZWxOZGxSWrqs4GInLIn+u99Q9q7p+GKni0=
github.com/go-toolsmith/astcast v1.0.0 h1:JojxlmI6STnFVG9yOImLeGREv8W2ocNUM+iOhR6jE7g=
github.com/go-toolsmith/astcast v1.0.0/go.mod h1:mt2OdQTeAQcY4DQgPSArJjHCcOwlX+Wl/kwN+LbLGQ4=
github.com/go-toolsmith/astequal v1.0.0/go.mod h1:H+xSiq0+LtiDC11+h1G32h7Of5O3CYFJ99GVbS5lDKY=
github.com/go-toolsmith/astequal v1.0.1 h1:JbSszi42Jiqu36Gnf363HWS9MTEAz67vTQLponh3Moc=
github.com/go-toolsmith/astequal v1.0.1/go.mod h1:4oGA3EZXTVItV/ipGiOx7NWkY5veFfcsOJVS2YxltLw=
-github.com/go-toolsmith/astinfo v0.0.0-20180906194353-9809ff7efb21/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=
github.com/go-toolsmith/astinfo v1.0.0 h1:rNuhpyhsnsze/Pe1l/GUHwxo1rmN7Dyb6oAnFcrXh+w=
github.com/go-toolsmith/astinfo v1.0.0/go.mod h1:dDStQCHtmZpYOmjRP/8gHHnCCch3Zz3oEgCdZVdtweU=
-github.com/go-toolsmith/pkgload v1.0.0/go.mod h1:5eFArkbO80v7Z0kdngIxsRXRMTaX4Ilcwuh3clNrQJc=
github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5 h1:eD9POs68PHkwrx7hAB78z1cb6PfGq/jyWn3wJywsH1o=
github.com/go-toolsmith/pkgload v1.0.2-0.20220101231613-e814995d17c5/go.mod h1:3NAwwmD4uY/yggRxoEjk/S00MIV3A+H7rrE3i87eYxM=
github.com/go-toolsmith/strparse v1.0.0 h1:Vcw78DnpCAKlM20kSbAyO4mPfJn/lyYA4BJUDxe2Jb4=
github.com/go-toolsmith/strparse v1.0.0/go.mod h1:YI2nUKP9YGZnL/L1/DLFBfixrcjslWct4wyljWhSRy8=
-github.com/go-toolsmith/typep v1.0.0/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
github.com/go-toolsmith/typep v1.0.2 h1:8xdsa1+FSIH/RhEkgnD1j2CJOy5mNllW1Q9tRiYwvlk=
github.com/go-toolsmith/typep v1.0.2/go.mod h1:JSQCQMUPdRlMZFswiq3TGpNp1GMktqkR2Ns5AIQkATU=
github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0=
@@ -285,6 +331,7 @@ github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/V
github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/gofrs/flock v0.8.1 h1:+gYjHKf32LDeiEEFhQaotPbLuUXjY5ZqxKgXy7n59aw=
+github.com/gofrs/flock v0.8.1/go.mod h1:F1TvTiK9OcQqauNUHlbJvyl9Qa1QvF/gOUDKA14jxHU=
github.com/gofrs/uuid v3.3.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
github.com/gofrs/uuid v4.4.0+incompatible h1:3qXRTX8/NbyulANqlc0lchS1gqAVxRgsuW1YrTJupqA=
github.com/gofrs/uuid v4.4.0+incompatible/go.mod h1:b2aQJv3Z4Fp6yNu3cdSllBxTCLRxnplIgP/c0N/04lM=
@@ -294,11 +341,11 @@ github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7a
github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
-github.com/golang-jwt/jwt/v4 v4.0.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
-github.com/golang-jwt/jwt/v4 v4.1.0 h1:XUgk2Ex5veyVFVeLm0xhusUTQybEbexJXrvPNOKkSY0=
-github.com/golang-jwt/jwt/v4 v4.1.0/go.mod h1:/xlHOz8bRuivTWchD4jCa+NbatV+wEUSzwAxVc6locg=
+github.com/golang-jwt/jwt/v4 v4.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
+github.com/golang-jwt/jwt/v4 v4.5.0/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe h1:lXe2qZdvpiX5WZkZR4hgp4KJVfY3nMkvmwbVkpv1rVY=
github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/glog v1.1.0 h1:/d3pCKDPWNnvIWe0vVUpNP32qc8U3PDVxySP/y360qE=
github.com/golang/glog v1.1.0/go.mod h1:pfYeQZ3JWZoXTV5sFc986z3HTpwQs9At6P4ImfuP3NQ=
@@ -352,20 +399,19 @@ github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/
github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
-github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
+github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE=
github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q=
github.com/google/go-dap v0.9.1 h1:d8dETjgHMR9/xs+Xza+NrZmB7jxIS5OtM2uRsyJVA/c=
github.com/google/go-dap v0.9.1/go.mod h1:HAeyoSd2WIfTfg+0GRXcFrb+RnojAtGNh+k+XTIxJDE=
-github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ=
github.com/google/go-github/v33 v33.0.0 h1:qAf9yP0qc54ufQxzwv+u9H0tiVOnPJxo0lI/JXqw3ZM=
github.com/google/go-github/v33 v33.0.0/go.mod h1:GMdDnVZY/2TsWgp/lkYnpSAh6TrzhANBBwm6k6TTEXg=
-github.com/google/go-github/v39 v39.2.0 h1:rNNM311XtPOz5rDdsJXAp2o8F67X9FnROXTvto3aSnQ=
-github.com/google/go-github/v39 v39.2.0/go.mod h1:C1s8C5aCC9L+JXIYpJM5GYytdX52vC1bLvHEF1IhBrE=
-github.com/google/go-github/v41 v41.0.0 h1:HseJrM2JFf2vfiZJ8anY2hqBjdfY1Vlj/K27ueww4gg=
-github.com/google/go-github/v41 v41.0.0/go.mod h1:XgmCA5H323A9rtgExdTcnDkcqp6S30AVACCBDOonIxg=
+github.com/google/go-github/v53 v53.2.0 h1:wvz3FyF53v4BK+AsnvCmeNhf8AkTaeh2SoYu/XUvTtI=
+github.com/google/go-github/v53 v53.2.0/go.mod h1:XhFRObz+m/l+UCm9b7KSIC3lT3NWSXGt7mOsAWEloao=
+github.com/google/go-github/v55 v55.0.0 h1:4pp/1tNMB9X/LuAhs5i0KQAE40NmiR/y6prLNb9x9cg=
+github.com/google/go-github/v55 v55.0.0/go.mod h1:JLahOTA1DnXzhxEymmFF5PP2tSS9JVNj68mSZNDwskA=
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck=
github.com/google/go-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8=
github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU=
@@ -385,32 +431,35 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe
github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20201218002935-b9804c9f04c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE=
github.com/google/pprof v0.0.0-20211214055906-6f57359322fd/go.mod h1:KgnwoLYCZ8IQu3XUZ8Nc/bM9CCZFOyjUNOSygVozoDg=
-github.com/google/pprof v0.0.0-20230602150820-91b7bce49751 h1:hR7/MlvK23p6+lIw9SN1TigNLn9ZnF3W4SYRKq2gAHs=
-github.com/google/pprof v0.0.0-20230602150820-91b7bce49751/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
+github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8 h1:n6vlPhxsA+BW/XsS5+uqi7GyzaLa5MH7qlSLBZtRdiA=
+github.com/google/pprof v0.0.0-20230705174524-200ffdc848b8/go.mod h1:Jh3hGz2jkYak8qXPD19ryItVnUgpgeqzdkY/D0EaeuA=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
+github.com/google/s2a-go v0.1.4 h1:1kZ/sQM3srePvKs3tXAvQzo66XfcReoqFpIpIccE7Oc=
+github.com/google/s2a-go v0.1.4/go.mod h1:Ej+mSEMGRnqRzjc7VtF+jdBwYG5fuJfiZ8ELkjEwM0A=
+github.com/google/safehtml v0.0.2/go.mod h1:L4KWwDsUJdECRAEpZoBn3O64bQaywRscowZjJAzjHnU=
github.com/google/subcommands v1.0.1/go.mod h1:ZjhPrFU+Olkh9WazFPsl27BQ4UPiG37m3yTrtFlrHVk=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
-github.com/googleapis/enterprise-certificate-proxy v0.2.3 h1:yk9/cqRKtT9wXZSsRH9aurXEpJX+U6FLtpYTdC3R06k=
-github.com/googleapis/enterprise-certificate-proxy v0.2.3/go.mod h1:AwSRAtLfXpU5Nm3pW+v7rGDHp09LsPtGY9MduiEsR9k=
+github.com/googleapis/enterprise-certificate-proxy v0.2.5 h1:UR4rDjcgpgEnqpIEvkiqTYKBCKLNmlge2eVjoZfySzM=
+github.com/googleapis/enterprise-certificate-proxy v0.2.5/go.mod h1:RxW0N9901Cko1VOCW3SXCpWP+mlIEkk2tP7jnHy9a3w=
github.com/googleapis/gax-go v0.0.0-20161107002406-da06d194a00e/go.mod h1:SFVmujtThgffbyetf+mdk2eWhX2bMyUtNHzFKcPA9HY=
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/googleapis/gax-go/v2 v2.7.1 h1:gF4c0zjUP2H/s/hEGyLA3I0fA2ZWjzYiONAD6cvPr8A=
-github.com/googleapis/gax-go/v2 v2.7.1/go.mod h1:4orTrqY6hXxxaUL4LHIPl6lGo8vAE38/qKbhSAKP6QI=
+github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas=
+github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU=
github.com/googleapis/google-cloud-go-testing v0.0.0-20200911160855-bcd43fbb19e8/go.mod h1:dvDLG8qkwmyD9a/MJJN3XJcT3xFxOKAvTZGvuZmac9g=
github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY=
github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4=
github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q=
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
-github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA=
github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs=
github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk=
github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms=
-github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg=
+github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0 h1:RtRsiaGvWxcwd8y3BiRZxsylPT8hLWZ5SPcfI+3IDNk=
+github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.0/go.mod h1:TzP6duP4Py2pHLVPPQp42aoYI92+PCrVotyR5e8Vqlk=
github.com/hashicorp/consul/api v1.1.0/go.mod h1:VmuI/Lkw1nC05EYQWNKwWGbkg+FbDBtguAZLlVdkD9Q=
github.com/hashicorp/consul/sdk v0.1.1/go.mod h1:VKf9jXwCTEY1QZP2MOLRhb5i/I/ssyNV1vwHyQBF0x8=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
@@ -419,11 +468,12 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
github.com/hashicorp/go-hclog v1.2.0 h1:La19f8d7WIlm4ogzNHB0JGqs5AUDAZ2UfCY4sJXcJdM=
+github.com/hashicorp/go-hclog v1.2.0/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ=
github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60=
github.com/hashicorp/go-msgpack v0.5.3/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
-github.com/hashicorp/go-retryablehttp v0.7.0 h1:eu1EI/mbirUgP5C8hVsTNaGZreBDlYiwC1FZWkvQPQ4=
-github.com/hashicorp/go-retryablehttp v0.7.0/go.mod h1:vAew36LZh98gCBJNLH42IQ1ER/9wtLZZ8meHqQvEYWY=
+github.com/hashicorp/go-retryablehttp v0.7.2 h1:AcYqCvkpalPnPF2pn0KamgwamS42TqUDDYFRKq/RAd0=
+github.com/hashicorp/go-retryablehttp v0.7.2/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8=
github.com/hashicorp/go-rootcerts v1.0.0/go.mod h1:K6zTfqpRlCUIjkwsN4Z+hiSfzSTQa6eBIzfwKfwNnHU=
github.com/hashicorp/go-sockaddr v1.0.0/go.mod h1:7Xibr9yA9JjQq1JpNB2Vw7kxv8xerXegt+ozgdvDeDU=
github.com/hashicorp/go-syslog v1.0.0/go.mod h1:qPfqrKkXGihmCqbJM2mZgkZGvKG1dFdvsLplgctolz4=
@@ -446,8 +496,9 @@ github.com/haya14busa/go-checkstyle v0.0.0-20170303121022-5e9d09f51fa1/go.mod h1
github.com/haya14busa/go-sarif v0.0.0-20210102043135-e2c5fed2fa3d/go.mod h1:1Hkn3JseGMB/hv1ywzkapVQDWV3bFgp6POZobZmR/5g=
github.com/hexops/gotextdiff v1.0.3 h1:gitA9+qJrrTCsiCl7+kh75nPqQt1cx4ZkudSTLoUqJM=
github.com/hexops/gotextdiff v1.0.3/go.mod h1:pSWU5MAI3yDq+fZBTazCSJysOMbxWL1BSow5/V2vxeg=
-github.com/huandu/xstrings v1.3.1 h1:4jgBlKK6tLKFvO8u5pmYjG91cqytmDCDvGh7ECVFfFs=
-github.com/huandu/xstrings v1.3.1/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/huandu/xstrings v1.3.3/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
+github.com/huandu/xstrings v1.4.0 h1:D17IlohoQq4UcpqD7fDk80P7l+lwAmlFaBHgOipl2FU=
+github.com/huandu/xstrings v1.4.0/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
github.com/iancoleman/orderedmap v0.2.0 h1:sq1N/TFpYH++aViPcaKjys3bDClUEU7s5B+z6jq8pNA=
github.com/iancoleman/orderedmap v0.2.0/go.mod h1:N0Wam8K1arqPXNWjMo21EXnBPOPp36vB07FNRdD2geA=
github.com/iancoleman/strcase v0.2.0 h1:05I4QRnGpI0m37iZQRuskXh+w77mr6Z41lwQzuHLwW0=
@@ -456,8 +507,8 @@ github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:
github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
github.com/ianlancetaylor/demangle v0.0.0-20210905161508-09a460cdf81d/go.mod h1:aYm2/VgdVmcIU8iMfdMvDMsRAQjcfZSKFby6HOFvi/w=
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
-github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
-github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
+github.com/imdario/mergo v0.3.16 h1:wwQJbIsHYGMUyLSPrEq1CT16AhnhNJQ51+4fdHUnCl4=
+github.com/imdario/mergo v0.3.16/go.mod h1:WBLT9ZmE3lPoWsEzCh9LPo3TiwVN+ZKEjmz+hD27ysY=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/inconshreveable/mousetrap v1.1.0 h1:wN+x4NVGpMsO7ErUn/mUI3vEoE6Jt13X2s0bqwp9tc8=
github.com/inconshreveable/mousetrap v1.1.0/go.mod h1:vpF70FUmC8bwa3OWnCshd2FqLfsEA9PFc4w1p2J65bw=
@@ -465,15 +516,16 @@ github.com/jackc/fake v0.0.0-20150926172116-812a484cc733 h1:vr3AYkKovP8uR8AvSGGU
github.com/jackc/fake v0.0.0-20150926172116-812a484cc733/go.mod h1:WrMFNQdiFJ80sQsxDoMokWK1W5TQtxBFNpzWTD84ibQ=
github.com/jackc/pgx v3.6.2+incompatible h1:2zP5OD7kiyR3xzRYMhOcXVvkDZsImVXfj+yIyTQf3/o=
github.com/jackc/pgx v3.6.2+incompatible/go.mod h1:0ZGrqGqkRlliWnWB4zKnWtjbSWbGkVEFm4TeybAXq+I=
+github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
+github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84 h1:2uT3aivO7NVpUPGcQX7RbHijHMyWix/yCnIrCWc+5co=
github.com/jdxcode/netrc v0.0.0-20221124155335-4616370d1a84/go.mod h1:Zi/ZFkEqFHTm7qkjyNJjaWH4LQA9LQhGJyF0lTYGpxw=
-github.com/jellevandenhooff/dkim v0.0.0-20150330215556-f50fe3d243e1/go.mod h1:E0B/fFc00Y+Rasa88328GlI/XbtyysCtTHZS8h7IrBU=
github.com/jessevdk/go-flags v1.5.0 h1:1jKYvbxEjfUl0fmqTCOfonvskHHXMjBySTLW4y9LFvc=
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c=
+github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo=
github.com/jinzhu/copier v0.3.5 h1:GlvfUwHk62RokgqVNvYsku0TATCF7bAHVwEXoBh3iJg=
github.com/jinzhu/copier v0.3.5/go.mod h1:DfbEm0FYsaqBcKcFuvmOZb218JkPGtvSHsKg8S8hyyg=
-github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik=
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
@@ -485,15 +537,19 @@ github.com/jstemmer/go-junit-report v1.0.0 h1:8X1gzZpR+nVQLAht+L/foqOeX2l9DTZoaI
github.com/jstemmer/go-junit-report v1.0.0/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
+github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
+github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4=
github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA=
+github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4=
+github.com/kevinburke/ssh_config v1.2.0/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
-github.com/klauspost/compress v1.16.6 h1:91SKEy4K37vkp255cJ8QesJhjyRO0hn9i9G0GoUwLsk=
-github.com/klauspost/compress v1.16.6/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
+github.com/klauspost/compress v1.16.7 h1:2mk3MPGNzKyxErAw8YaohYh69+pa4sIQSC0fPGCFR9I=
+github.com/klauspost/compress v1.16.7/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/pgzip v1.2.6 h1:8RXeL5crjEUFnR2/Sn6GJNWtSQ3Dk8pq4CL3jvdDyjU=
github.com/klauspost/pgzip v1.2.6/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
@@ -506,11 +562,11 @@ github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfn
github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE=
github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/pty v1.1.3/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
+github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
github.com/lib/pq v1.8.0/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
github.com/lib/pq v1.10.6 h1:jbk+ZieJ0D7EVGJYpL9QTz7/YW6UHbmdnZWYyK5cdBs=
github.com/lib/pq v1.10.6/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=
@@ -526,6 +582,8 @@ github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE=
github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0=
+github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
+github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
@@ -541,13 +599,15 @@ github.com/mattn/go-runewidth v0.0.13/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-sqlite3 v1.14.0/go.mod h1:JIl7NbARA7phWnGvh0LKTyg7S9BA+6gx71ShQilpsus=
-github.com/mattn/go-sqlite3 v1.14.5 h1:1IdxlwTNazvbKJQSxoJ5/9ECbEeaTTyeU7sEAZ5KKTQ=
github.com/mattn/go-sqlite3 v1.14.5/go.mod h1:WVKg1VTActs4Qso6iwGbiFih2UIHo0ENGwNd0Lj+XmI=
+github.com/mattn/go-sqlite3 v1.14.6 h1:dNPt6NO46WmLVt2DLNpwczCmdV5boIZ6g/tlDrlRUbg=
+github.com/mattn/go-sqlite3 v1.14.6/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
-github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
+github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
+github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
@@ -561,8 +621,8 @@ github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RR
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
-github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
-github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
+github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
+github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -576,8 +636,8 @@ github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4=
github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U=
github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
-github.com/opencontainers/image-spec v1.1.0-rc3 h1:fzg1mXZFj8YdPeNkRXMg+zb88BFV0Ys52cJydRwBkb8=
-github.com/opencontainers/image-spec v1.1.0-rc3/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
+github.com/opencontainers/image-spec v1.1.0-rc4 h1:oOxKUJWnFC4YGHCCMNql1x4YaDfYBTS5Y4x/Cgeo1E0=
+github.com/opencontainers/image-spec v1.1.0-rc4/go.mod h1:X4pATf0uXsnn3g5aiGIsVnJBR4mxhKzfwmvK/B2NTm8=
github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs=
github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc=
github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
@@ -585,6 +645,11 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9
github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE=
github.com/pelletier/go-toml/v2 v2.0.6 h1:nrzqCb7j9cDFj2coyLNLaZuJTLjWjlaz6nvTvIwycIU=
github.com/pelletier/go-toml/v2 v2.0.6/go.mod h1:eumQOmlWiOPt5WriQQqoM5y18pDHwha2N+QD+EUNTek=
+github.com/phpdave11/gofpdf v1.4.2/go.mod h1:zpO6xFn9yxo3YLyMvW8HcKWVdbNqgIfOOp2dXMnm1mY=
+github.com/phpdave11/gofpdi v1.0.12/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
+github.com/phpdave11/gofpdi v1.0.13/go.mod h1:vBmVV0Do6hSBHC8uKUQ71JGW+ZGQq74llk/7bXwjDoI=
+github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4=
+github.com/pjbgf/sha1cd v0.3.0/go.mod h1:nZ1rrWOcGJ5uZgEEVL1VUM9iRQiZvWdbZjkKyFzPPsI=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8 h1:KoWmjvw+nsYOo29YJK9vDA65RGE3NrOnUtO7a+RF9HU=
github.com/pkg/browser v0.0.0-20210911075715-681adbf594b8/go.mod h1:HKlIX3XHQyzLZPlr7++PzdhaXEj94dEiJgZDTsxEqUI=
github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA=
@@ -608,19 +673,20 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
-github.com/quasilyte/go-consistent v0.0.0-20200404105227-766526bf1e96 h1:6VBkISnfYpPtRvpE9wsVoxX+i0cDQFBPQPYzw259xWY=
-github.com/quasilyte/go-consistent v0.0.0-20200404105227-766526bf1e96/go.mod h1:h5ob45vcE3sydtmo0lUDUmG3Y0HXudxMId1w+5G99VI=
+github.com/quasilyte/go-consistent v0.6.0 h1:tY8DYfgM+7ADpOyr5X47i8hV/XbMNoucqnqZWVjI+rU=
+github.com/quasilyte/go-consistent v0.6.0/go.mod h1:dKYK1JZl3150J1+Jh4cDYPCIu2MqybUBi0YVW2b2E6c=
github.com/reva2/bitbucket-insights-api v1.0.0 h1:lpQ/Q7OmnG04w/EM77piOwZBxP41PeTlbytXxVrnplA=
github.com/reva2/bitbucket-insights-api v1.0.0/go.mod h1:pLs+ki3MKUntrPryxaGIvpRLiEtBhwfJ/uvxQIMfqHU=
-github.com/reviewdog/errorformat v0.0.0-20220309155058-b075c45b6d9a h1:HIL+jTKsWmNT5WoTNwHQ0jUNJpFOmgeHLOsHMZInrF8=
-github.com/reviewdog/errorformat v0.0.0-20220309155058-b075c45b6d9a/go.mod h1:AqhrP0G7F9YRROF10JQwdd4cNO8bdm6bY6KzcOc3Cp8=
+github.com/reviewdog/errorformat v0.0.0-20230810075619-82e5d4ad20d2 h1:oP5DZdUlH2M1Luf2NdNhJ6TM/NiPn6wZy1QI5ybYsro=
+github.com/reviewdog/errorformat v0.0.0-20230810075619-82e5d4ad20d2/go.mod h1:AqhrP0G7F9YRROF10JQwdd4cNO8bdm6bY6KzcOc3Cp8=
github.com/reviewdog/go-bitbucket v0.0.0-20201024094602-708c3f6a7de0 h1:XZ60Bp2UqwaJ6fDQExoFVrgs4nIzwBCy9ct6GCj9hH8=
github.com/reviewdog/go-bitbucket v0.0.0-20201024094602-708c3f6a7de0/go.mod h1:5JbWAMFyq9hbISZawRyIe7QTcLaptvCIvmZnYo+1VvA=
-github.com/reviewdog/reviewdog v0.14.1 h1:+B2340ddsSC+tbSSTxb5oC24YPMLzQAlt4kVAmNS/3o=
-github.com/reviewdog/reviewdog v0.14.1/go.mod h1:408Nr2GPWc7Qozz0X1RZ/3b7EVQIPJ6XF6BssRJ8ZKY=
+github.com/reviewdog/reviewdog v0.15.0 h1:uj61ifLBGGshd7HfezG8Vllpc4b7Y47zHLZFxfxZOi0=
+github.com/reviewdog/reviewdog v0.15.0/go.mod h1:ea/9hMRfJKPzfaSBs46KNFdN+2MExaKBohJZwweS8AQ=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
+github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
@@ -635,20 +701,27 @@ github.com/rs/zerolog v1.29.0/go.mod h1:NILgTygv/Uej1ra5XxGf82ZFSLk58MFGAUS2o6us
github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
+github.com/ruudk/golang-pdf417 v0.0.0-20181029194003-1af4ab5afa58/go.mod h1:6lfFZQK844Gfx8o5WFuvpxWRwnSoipWe/p622j1v06w=
+github.com/ruudk/golang-pdf417 v0.0.0-20201230142125-a7e3863a1245/go.mod h1:pQAZKsJ8yyVxGRWYNEm9oFB8ieLgKFnamEyDmSA0BRk=
github.com/ryanuber/columnize v0.0.0-20160712163229-9b3edd62028f/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts=
github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529/go.mod h1:DxrIzT+xaE7yg65j358z/aeFdxmN0P9QXhEzd20vsDc=
-github.com/shopspring/decimal v1.2.0 h1:abSATXmQEYyShuxI4/vyW3tV1MrKAJzCZ/0zLUXYbsQ=
+github.com/sergi/go-diff v1.3.1 h1:xkr+Oxo4BOQKmkn/B9eMK0g5Kg/983T9DqqPHwYqD+8=
+github.com/sergi/go-diff v1.3.1/go.mod h1:aMJSSKb2lpPvRNec0+w3fl7LP9IOFzdc9Pa4NFbPK1I=
github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
+github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8=
+github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
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/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
+github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
+github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM=
+github.com/skeema/knownhosts v1.2.0/go.mod h1:g4fPeYpque7P0xefxtGzV81ihjC8sX2IqpAoNkjxbMo=
github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc=
github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA=
github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM=
@@ -662,7 +735,6 @@ github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
github.com/spf13/cast v1.5.0/go.mod h1:SpXXQ5YoyJw6s3/6cMTQuxvgRl3PCJiyaX9p6b155UU=
github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo=
-github.com/spf13/cobra v1.4.0/go.mod h1:Wo4iy3BUC+X2Fybo0PDqwJIv3dNRiZLHQymsfxlB84g=
github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I=
github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0=
github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
@@ -689,12 +761,12 @@ github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/
github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU=
github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
+github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/subosito/gotenv v1.4.2 h1:X1TuBLAMDFbaTAChgCBLu3DU3UPyELpnF2jjJ2cz/S8=
github.com/subosito/gotenv v1.4.2/go.mod h1:ayKnFf/c6rvx/2iiLrJUk1e6plDbT3edrFNGqEflhK0=
-github.com/tarm/serial v0.0.0-20180830185346-98f6abe2eb07/go.mod h1:kDXzergiv9cbyO7IOYJZWg1U88JhDg3PB6klq9Hg2pA=
-github.com/tetratelabs/wazero v1.2.1 h1:J4X2hrGzJvt+wqltuvcSjHQ7ujQxA9gb6PeMs4qlUWs=
-github.com/tetratelabs/wazero v1.2.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
+github.com/tetratelabs/wazero v1.3.1 h1:rnb9FgOEQRLLR8tgoD1mfjNjMhFeWRUk+a4b4j/GpUM=
+github.com/tetratelabs/wazero v1.3.1/go.mod h1:wYx2gNRg8/WihJfSDxA1TIL8H+GkfLYm+bIfbblu9VQ=
github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4=
github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk=
github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U=
@@ -705,12 +777,14 @@ github.com/vbatts/tar-split v0.11.3 h1:hLFqsOLQ1SsppQNTMpkpPXClLDfC2A3Zgy9OUU+RV
github.com/vbatts/tar-split v0.11.3/go.mod h1:9QlHN18E+fEH7RdG+QAJJcuya3rqT7eXSTY7wGrAokY=
github.com/vburenin/ifacemaker v1.2.1 h1:3Vq8B/bfBgjWTkv+jDg4dVL1KHt3k1K4lO7XRxYA2sk=
github.com/vburenin/ifacemaker v1.2.1/go.mod h1:5WqrzX2aD7/hi+okBjcaEQJMg4lDGrpuEX3B8L4Wgrs=
-github.com/vektra/mockery/v2 v2.30.16 h1:XbUaK84eY7Hl/y6JeT7hVaA59Jgo4owlNWWgfL/gCQU=
-github.com/vektra/mockery/v2 v2.30.16/go.mod h1:9lREs4VEeQiUS3rizYQx1saxHu2JiIhThP0q9+fDegM=
-github.com/vvakame/sdlog v0.0.0-20200409072131-7c0d359efddc h1:El7LEavRpa49dYFE9ezO8aQxQn5E7u7eQkFsaXsoQAY=
-github.com/vvakame/sdlog v0.0.0-20200409072131-7c0d359efddc/go.mod h1:MmhrKtbECoUJTctfak+MnOFoJ9XQqYZ7chcwV9O7v3I=
-github.com/xanzy/go-gitlab v0.63.0 h1:a9fXpKWykUS6dowapFej/2Wjf4aOAEFC1q2ZIcz4IpI=
-github.com/xanzy/go-gitlab v0.63.0/go.mod h1:F0QEXwmqiBUxCgJm8fE9S+1veX4XC9Z4cfaAbqwk4YM=
+github.com/vektra/mockery/v2 v2.33.0 h1:C3W/EoEiBCdb8olVat+hcnqI8rebH4xmZzTP7FPoLSs=
+github.com/vektra/mockery/v2 v2.33.0/go.mod h1:9lREs4VEeQiUS3rizYQx1saxHu2JiIhThP0q9+fDegM=
+github.com/vvakame/sdlog v1.2.0 h1:gwZRXZ0EmhJQJN/Do/+PTQigcmFiSqZ07aDjxqGOLT8=
+github.com/vvakame/sdlog v1.2.0/go.mod h1:gFYv2g/iR3pJSxkJz0YnkNmhNbXT5R3PzWsfZKGQADY=
+github.com/xanzy/go-gitlab v0.91.1 h1:gnV57IPGYywWer32oXKBcdmc8dVxeKl3AauV8Bu17rw=
+github.com/xanzy/go-gitlab v0.91.1/go.mod h1:5ryv+MnpZStBH8I/77HuQBsMbBGANtVpLWC15qOjWAw=
+github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM=
+github.com/xanzy/ssh-agent v0.3.3/go.mod h1:6dzNDKs0J9rVPHPhaGCukekBHKqfl+L3KghI1Bc68Uw=
github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs=
github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM=
@@ -720,7 +794,6 @@ github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.4.1/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU=
go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg=
@@ -742,25 +815,27 @@ go.opentelemetry.io/otel/metric v1.16.0/go.mod h1:QE47cpOmkwipPiefDwo2wDzwJrlfxx
go.opentelemetry.io/otel/sdk v1.16.0 h1:Z1Ok1YsijYL0CSJpHt4cS3wDDh7p572grzNrBMiMWgE=
go.opentelemetry.io/otel/sdk v1.16.0/go.mod h1:tMsIuKXuuIWPBAOrH+eHtvhTL+SntFtXF9QD68aP6p4=
go.opentelemetry.io/otel/sdk/metric v0.39.0 h1:Kun8i1eYf48kHH83RucG93ffz0zGV1sh46FAScOTuDI=
+go.opentelemetry.io/otel/sdk/metric v0.39.0/go.mod h1:piDIRgjcK7u0HCL5pCA4e74qpK/jk3NiUoAHATVAmiI=
go.opentelemetry.io/otel/trace v1.16.0 h1:8JRpaObFoW0pxuVPapkgH8UhHQj+bJW8jJsCZEu5MQs=
go.opentelemetry.io/otel/trace v1.16.0/go.mod h1:Yt9vYq1SdNz3xdjZZK7wcXv1qv2pwLkqr2QVwea0ef0=
+go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI=
go.starlark.net v0.0.0-20220816155156-cfacd8902214 h1:MqijAN3S61c7KWasOk+zIqIjHQPN6WUra/X3+YAkQxQ=
go.starlark.net v0.0.0-20220816155156-cfacd8902214/go.mod h1:VZcBMdr3cT3PnBoWunTabuSEXwVAH+ZJ5zxfs3AdASk=
go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE=
go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE=
go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0=
go.uber.org/goleak v1.1.11 h1:wy28qYRKZgnJTxGxvye5/wgWr1EKjmUDGYox5mGlRlI=
+go.uber.org/goleak v1.1.11/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ=
go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0=
go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0=
go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y=
go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q=
go.uber.org/zap v1.24.0 h1:FiJd5l1UOLj0wCgbSE0rwwXHzEdAZS6hiiSnxJN/D60=
go.uber.org/zap v1.24.0/go.mod h1:2kMP+WWQ8aoFoedH3T2sq6iJ2yDWpHbP0f6MQbS9Gkg=
-go4.org v0.0.0-20180809161055-417644f6feb5/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE=
golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4 h1:QlVATYS7JBoZMVaf+cNjb90WD/beKVHnIxFKT4QaHVI=
golang.org/x/arch v0.0.0-20190927153633-4e8777c89be4/go.mod h1:flIaEI6LNU6xOCD5PaJvn9wGP0agmIOqjrtsKGRguv4=
-golang.org/x/build v0.0.0-20200616162219-07bebbe343e9 h1:SgmspiKqqI4Du0T87bPBEezUSzVOKhKDgconpLrfyuc=
-golang.org/x/build v0.0.0-20200616162219-07bebbe343e9/go.mod h1:ia5pRNoJUuxRhXkmwkySu4YBTbXHSKig2ie6daQXihg=
+golang.org/x/build v0.0.0-20230905185615-7f65e2bc812a h1:0XvhCUgBoH8lCN4oOJ/fshXfKKlqPYIXUC2KAJgWZI0=
+golang.org/x/build v0.0.0-20230905185615-7f65e2bc812a/go.mod h1:LblaorLo4w94wk4xZvKeLSaFLku6WbfOih5CoMhhvVc=
golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20181029021203-45a5f77698d3/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
@@ -770,28 +845,43 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
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-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
-golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20201216223049-8b5274cf687f/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
-golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20211108221036-ceb1ce70b4fa/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.0.0-20220518034528-6f7dac969898/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
-golang.org/x/crypto v0.10.0 h1:LKqV2xt9+kDzSTfOhx4FrkEBcMrAgHSYgzywV9zcGmM=
-golang.org/x/crypto v0.10.0/go.mod h1:o4eNf7Ede1fv+hwOwZsTHl9EsPFO6q6ZvYR8vYfY45I=
+golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
+golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
+golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU=
+golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
+golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
+golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
+golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/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-20191002040644-a1355ae1e2c3/go.mod h1:NOZ3BPKG0ec/BKJQgnvsSFpcKLM5xXVWnvZS97DWHgE=
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-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
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/image v0.0.0-20190910094157-69e4b8554b2a/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20200119044424-58c23975cae1/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20200430140353-33d19683fad8/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20200618115811-c13761719519/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20201208152932-35266b937fa6/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20210216034530-4410531fe030/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
+golang.org/x/image v0.0.0-20210607152325-775e3b0c77b9/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
+golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
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=
@@ -815,10 +905,10 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
-golang.org/x/mod v0.11.0 h1:bUO06HqtnRcc/7l71XBe4WcqTZ+3AH1J59zWDDwLKgU=
-golang.org/x/mod v0.11.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
+golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
+golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
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=
@@ -856,13 +946,15 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY
golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
-golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
+golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
-golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
-golang.org/x/net v0.0.0-20220517181318-183a9ca12b87/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
-golang.org/x/net v0.11.0 h1:Gi2tvZIJyBtO9SDr1q9h5hEQCp/4L2RQ+ar0qjx2oNU=
-golang.org/x/net v0.11.0/go.mod h1:2L/ixqYpgIVXmeoSA/4Lu7BzTG4KIyPIryS4IsOd1oQ=
+golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
+golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
+golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
+golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
+golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/oauth2 v0.0.0-20170207211851-4464e7848382/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
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=
@@ -873,12 +965,11 @@ golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20201109201403-9fd604954f58/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20201208152858-08078c50e5b5/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
-golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc=
-golang.org/x/oauth2 v0.8.0 h1:6dkIjl3j3LtZ/O3sTgZTMsLKSftL/B8Zgq4huOIIUu8=
golang.org/x/oauth2 v0.8.0/go.mod h1:yr7u4HXZRm1R1kBWqr/xKNqewf0plRYoB7sla+BCIXE=
-golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
-golang.org/x/perf v0.0.0-20211012211434-03971e389cd3 h1:TxpziJvKtFH7T75kH/tX3QELShnXGyWX1iVgw8hU9EY=
-golang.org/x/perf v0.0.0-20211012211434-03971e389cd3/go.mod h1:KRSrLY7jerMEa0Ih7gBheQ3FYDiSx6liMnniX1o3j2g=
+golang.org/x/oauth2 v0.12.0 h1:smVPGxink+n1ZI5pkQa8y6fZT0RW0MgCO5bFpepy4B4=
+golang.org/x/oauth2 v0.12.0/go.mod h1:A74bZ3aGXgCY0qaIC9Ahg6Lglin4AMAco8cIv9baba4=
+golang.org/x/perf v0.0.0-20230717203022-1ba3a21238c9 h1:HPASJO/sBgVQqFwIsL7A5o5GfTRe30dOhyX94F+4as0=
+golang.org/x/perf v0.0.0-20230717203022-1ba3a21238c9/go.mod h1:UBKtEnL8aqnd+0JHqZ+2qoMDwtuy6cYhhKNoHLBiTQc=
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/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -890,8 +981,8 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -935,7 +1026,9 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210104204734-6f8348627aad/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210225134936-a50acf3fe073/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/sys v0.0.0-20210304124612-50617c2ba197/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210423185535-09eb48e85fd7/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -946,23 +1039,29 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211117180635-dee7805ff2e1/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-20220517195934-5e4e11fc645e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s=
-golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
+golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
-golang.org/x/term v0.9.0 h1:GRRCnKYhdQrD8kfRAdQ6Zcw1P0OcELxGLKJvtjVMZ28=
-golang.org/x/term v0.9.0/go.mod h1:M6DEAAIenWoTxdKrOltXcmDY3rSplQUkrvaDU5FcQyo=
+golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
+golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
+golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U=
+golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.12.0 h1:/ZfYdc3zq+q02Rv9vGqTeSItdzZTSNDmfTi0mBAuidU=
+golang.org/x/term v0.12.0/go.mod h1:owVbMEjm3cBLCHdkQu9b1opXd4ETQWc3BhuQGKgXgvU=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
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=
@@ -972,17 +1071,23 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
-golang.org/x/text v0.10.0 h1:UpjohKhiEgNc0CSauXmwYftY1+LlaC75SJwh0SgCX58=
-golang.org/x/text v0.10.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
+golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
+golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
+golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
+golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
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/time v0.1.0 h1:xYY+Bajn2a7VBmTM5GikTmnK8ZuX8YgnQCqZpbBNtmA=
-golang.org/x/time v0.1.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
+golang.org/x/time v0.3.0 h1:rg5rLMjNzMS1RkNLzCG38eapWhnYLFYXDXj2gOlr8j4=
+golang.org/x/time v0.3.0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
+golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
-golang.org/x/tools v0.0.0-20190110163146-51295c7ec13a/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-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20190221204921-83362c3779f5/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY=
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=
@@ -1001,6 +1106,7 @@ golang.org/x/tools v0.0.0-20190621195816-6e04913cbbac/go.mod h1:/rFqwRUd4F7ZHNgw
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-20190927191325-030b2cf1153e/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-20191112195655-aa38f8e97acc/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.0.0-20191113191852-77e3bb0ad9e7/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
@@ -1020,9 +1126,7 @@ golang.org/x/tools v0.0.0-20200224181240-023911ca70b2/go.mod h1:TB2adYChydJhpapK
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-20200329025819-fd4102a86c65/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
golang.org/x/tools v0.0.0-20200331025713-a30bf2db82d4/go.mod h1:Sl4aGygMT6LrqrWclx+PTx3U+LnKx/seiNR+3G19Ar8=
-golang.org/x/tools v0.0.0-20200406213809-066fd1390ee0/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
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=
@@ -1039,17 +1143,23 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.0.0-20210108195828-e2f9c7f1fc8e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0=
-golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
-golang.org/x/tools v0.10.0 h1:tvDr/iQoUqNdohiYm0LmmKcBk+q86lb9EprIUFhHHGg=
-golang.org/x/tools v0.10.0/go.mod h1:UJwyiVBsOA2uwvK/e5OY3GTpDUJriEd+/YlqAwLPmyM=
+golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
+golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ=
+golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58=
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=
-golang.org/x/xerrors v0.0.0-20220517211312-f3a8303e98df/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 h1:H2TDz8ibqkAF6YGhCdN3jS9O0/s90v0rJh3X/OLHEUk=
golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2/go.mod h1:K8+ghG5WaK9qNqU5K3HdILfMLy1f3aNYFI/wnl100a8=
+gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo=
+gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0=
+gonum.org/v1/gonum v0.9.3/go.mod h1:TZumC3NeyVQskjXqmyWt4S3bINhy7B4eYwW69EbyX+0=
+gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw=
+gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc=
+gonum.org/v1/plot v0.9.0/go.mod h1:3Pcqqmp6RHvJI72kgb8fThyUnav364FOsdDo2aGW5lY=
+gonum.org/v1/plot v0.10.0/go.mod h1:JWIHJ7U20drSQb/aDpTetJzfC1KlAPldJLpkSy88dvQ=
google.golang.org/api v0.0.0-20170206182103-3d017632ea10/go.mod h1:4mhQ8q/RsB7i+udVvVy5NUi08OU8ZlA0gRVgrF7VFY0=
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=
@@ -1070,16 +1180,17 @@ google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz513
google.golang.org/api v0.35.0/go.mod h1:/XrVsuzM0rZmrsbjJutiuftIzeuTQcEeaYcSk/mQ1dg=
google.golang.org/api v0.36.0/go.mod h1:+z5ficQTmoYpPn8LCUNVpK5I7hwkpjbcgqA7I34qYtE=
google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjRCQ8=
-google.golang.org/api v0.114.0 h1:1xQPji6cO2E2vLiI+C/XiFAnsn1WV3mjaEwGLhi3grE=
-google.golang.org/api v0.114.0/go.mod h1:ifYI2ZsFK6/uGddGfAD5BMxlnkBqCmqHSDUVi45N5Yg=
+google.golang.org/api v0.128.0 h1:RjPESny5CnQRn9V6siglged+DZCgfu9l6mO9dkX9VOg=
+google.golang.org/api v0.128.0/go.mod h1:Y611qgqaE92On/7g65MQgxYul3c0rEB894kniWLY750=
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/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
-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/appengine v1.6.8-0.20221117013220-504804fb50de h1:MvEeYmzkzk0Rsw+ceqy28aIJN7Mum+4aYqBwCMqYNug=
+google.golang.org/appengine v1.6.8-0.20221117013220-504804fb50de/go.mod h1:BbwiCY3WCmCUKOJTrX5NwgQzew1c32w3kxa6Sxvs0cQ=
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=
@@ -1103,6 +1214,7 @@ google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfG
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-20200513103714-09dca8ec2884/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=
@@ -1116,12 +1228,12 @@ google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6D
google.golang.org/genproto v0.0.0-20201214200347-8c77b98c765d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210108203827-ffc7fda8c3d7/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
google.golang.org/genproto v0.0.0-20210226172003-ab064af71705/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no=
-google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e h1:Ao9GzfUMPH3zjVfzXG5rlWlk+Q8MXWKwWpwVQE1MXfw=
-google.golang.org/genproto v0.0.0-20230526203410-71b5a4ffd15e/go.mod h1:zqTuNwFlFRsw5zIts5VnzLQxSRqh+CGOTVMlYbY0Eyk=
-google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc h1:kVKPf/IiYSBWEWtkIn6wZXwWGCnLKcC8oWfZvXjsGnM=
-google.golang.org/genproto/googleapis/api v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:vHYtlOoi6TsQ3Uk2yxR7NI5z8uoV+3pZtR4jmHIkRig=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc h1:XSJ8Vk1SWuNr8S18z1NZSziL0CPIXLCCMDOEFtHBOFc=
-google.golang.org/genproto/googleapis/rpc v0.0.0-20230530153820-e85fd2cbaebc/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA=
+google.golang.org/genproto v0.0.0-20230821184602-ccc8af3d0e93 h1:zv6ieVm8jNcN33At1+APsRISkRgynuWUxUhv6G123jY=
+google.golang.org/genproto v0.0.0-20230821184602-ccc8af3d0e93/go.mod h1:yZTlhN0tQnXo3h00fuXNCxJdLdIdnVFVBaRJ5LWBbw4=
+google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d h1:DoPTO70H+bcDXcd39vOqb2viZxgqeBeSGtZ55yZU4/Q=
+google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d/go.mod h1:KjSP20unUpOx5kyQUFa7k4OJg0qeJ7DEZflGDu2p6Bk=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
+google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
google.golang.org/grpc v0.0.0-20170208002647-2a6bf6142e96/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
@@ -1136,11 +1248,14 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji
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/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak=
+google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0=
google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc=
google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8=
google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
-google.golang.org/grpc v1.55.0 h1:3Oj82/tFSCeUrRTg/5E/7d/W5A1tj6Ky1ABAuZuv5ag=
-google.golang.org/grpc v1.55.0/go.mod h1:iYEXKGkEBhg1PjZQvoYEVPTDkHo1/bjTnfwTeGONTY8=
+google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU=
+google.golang.org/grpc v1.45.0/go.mod h1:lN7owxKUQEqMfSyQikvvk5tf/6zMPsrK+ONuO11+0rQ=
+google.golang.org/grpc v1.58.0 h1:32JY8YpPMSR45K+c3o6b8VL73V+rR8k+DeMIr4vRH8o=
+google.golang.org/grpc v1.58.0/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0 h1:rNBFJjBCOgVr9pWD7rs/knKL4FRTKgpZmsRfV214zcA=
google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.3.0/go.mod h1:Dk1tviKTvMCz5tvh7t+fh94dhmQVHuCt2OzJB3CTW9Y=
google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8=
@@ -1162,20 +1277,24 @@ gopkg.in/alecthomas/kingpin.v2 v2.2.6 h1:jMFz6MfLP0/4fUyZle81rXUoxOBFi19VUFKVDOQ
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200902074654-038fdea0a05b/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
+gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
-gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw=
gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/ini.v1 v1.67.0 h1:Dgnx+6+nfE+IfzjUEISNeydPJh9AXNNsWbGP9KzCsOA=
gopkg.in/ini.v1 v1.67.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
gopkg.in/reform.v1 v1.5.1 h1:7vhDFW1n1xAPC6oDSvIvVvpRkaRpXlxgJ4QB4s3aDdo=
gopkg.in/reform.v1 v1.5.1/go.mod h1:AIv0CbDRJ0ljQwptGeaIXfpDRo02uJwTq92aMFELEeU=
gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo=
+gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
+gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74=
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
+gopkg.in/yaml.v2 v2.2.3/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.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
@@ -1185,11 +1304,10 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
-gopkg.in/yaml.v3 v3.0.0-20220512140231-539c8e751b99/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0=
-grpc.go4.org v0.0.0-20170609214715-11d0a25b4919/go.mod h1:77eQGdRu53HpSqPFJFmuJdjuHRquDANNeA4x7B8WQ9o=
+gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8=
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=
diff --git a/tools/tools.go b/tools/tools.go
index bbe45acd65..bac23abc14 100644
--- a/tools/tools.go
+++ b/tools/tools.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2021 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/.devcontainer/install-dev-tools.sh b/update/.devcontainer/install-dev-tools.sh
index 861f1aeed9..366832539d 100755
--- a/update/.devcontainer/install-dev-tools.sh
+++ b/update/.devcontainer/install-dev-tools.sh
@@ -8,7 +8,7 @@ set -o errexit
set -o xtrace
# download (in the background) the same verison as used by PMM build process
-curl -sS https://dl.google.com/go/go1.20.5.linux-amd64.tar.gz -o /tmp/golang.tar.gz &
+curl -sS https://dl.google.com/go/go1.21.1.linux-amd64.tar.gz -o /tmp/golang.tar.gz &
# to install man pages
sed -i '/nodocs/d' /etc/yum.conf
diff --git a/update/ansible/playbook/tasks/files/change-admin-password b/update/ansible/playbook/tasks/files/change-admin-password
index 60f2484470..1a8b9f8819 100644
--- a/update/ansible/playbook/tasks/files/change-admin-password
+++ b/update/ansible/playbook/tasks/files/change-admin-password
@@ -2,4 +2,4 @@
#
# Change password for default admin user in PMM
-grafana-cli --config=/etc/grafana/grafana.ini --homepath /usr/share/grafana --configOverrides cfg:default.paths.data=/srv/grafana admin reset-admin-password $1
+grafana cli --config=/etc/grafana/grafana.ini --homepath /usr/share/grafana admin reset-admin-password $1
diff --git a/update/ansible/playbook/tasks/files/datasources.yml b/update/ansible/playbook/tasks/files/datasources.yml
index 79ba5ebcd0..b11fa2d0c8 100644
--- a/update/ansible/playbook/tasks/files/datasources.yml
+++ b/update/ansible/playbook/tasks/files/datasources.yml
@@ -8,7 +8,7 @@ datasources:
orgId: 1
type: prometheus
access: proxy
- url: http://127.0.0.1:8430/prometheus/
+ url: http://127.0.0.1:8430/
isDefault: true
jsonData:
httpMethod: POST
diff --git a/update/ansible/playbook/tasks/files/maintenance.html b/update/ansible/playbook/tasks/files/maintenance.html
new file mode 100644
index 0000000000..8056396816
--- /dev/null
+++ b/update/ansible/playbook/tasks/files/maintenance.html
@@ -0,0 +1,14 @@
+
+
+
+
+
+
+
+ Maintenance Mode
+
+
+PMM is being upgraded
+Please wait until the upgrade process is finished.
+
+
\ No newline at end of file
diff --git a/update/ansible/playbook/tasks/init.yml b/update/ansible/playbook/tasks/init.yml
index 828b8055c6..5c27f29b2d 100644
--- a/update/ansible/playbook/tasks/init.yml
+++ b/update/ansible/playbook/tasks/init.yml
@@ -4,6 +4,6 @@
become: true
gather_facts: true
tasks:
- - name: Run initializaion role
+ - name: Run initialization role
include_role:
name: initialization
diff --git a/update/ansible/playbook/tasks/roles/clickhouse/tasks/main.yml b/update/ansible/playbook/tasks/roles/clickhouse/tasks/main.yml
index 2fb89b954b..ab927c62b5 100644
--- a/update/ansible/playbook/tasks/roles/clickhouse/tasks/main.yml
+++ b/update/ansible/playbook/tasks/roles/clickhouse/tasks/main.yml
@@ -1,6 +1,8 @@
---
- name: Stop and remove clickhouse before update | EL7
- when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'
+ when:
+ - ansible_distribution == 'CentOS'
+ - ansible_distribution_major_version == '7'
command: supervisorctl {{ item }} clickhouse
changed_when: True
loop:
@@ -13,7 +15,10 @@
register: supervisord_socket
- name: Stop and remove clickhouse before update | EL9
- when: supervisord_socket.stat.exists and (ansible_distribution == 'OracleLinux' or ansible_distribution == 'AlmaLinux') and ansible_distribution_major_version == '9'
+ when:
+ - supervisord_socket.stat.exists
+ - ansible_distribution == 'OracleLinux' or ansible_distribution == 'AlmaLinux'
+ - ansible_distribution_major_version == '9'
command: /usr/local/bin/supervisorctl {{ item }} clickhouse
become: true
loop:
@@ -61,7 +66,7 @@
name: clickhouse
file: clickhouse
description: "Clickhouse repo"
- baseurl: "https://repo.clickhouse.com/rpm/stable/x86_64/"
+ baseurl: "https://packages.clickhouse.com/rpm/stable/"
enabled: no
gpgcheck: 1
gpgkey: "https://repo.clickhouse.com/CLICKHOUSE-KEY.GPG"
@@ -74,7 +79,7 @@
name: clickhouse
file: clickhouse
description: "Clickhouse repo"
- baseurl: "https://repo.clickhouse.com/rpm/stable/x86_64/"
+ baseurl: "https://packages.clickhouse.com/rpm/stable/"
enabled: no
gpgcheck: 0
diff --git a/update/ansible/playbook/tasks/roles/dashboards_upgrade/tasks/main.yml b/update/ansible/playbook/tasks/roles/dashboards_upgrade/tasks/main.yml
index 022621b028..7c5080cfa9 100644
--- a/update/ansible/playbook/tasks/roles/dashboards_upgrade/tasks/main.yml
+++ b/update/ansible/playbook/tasks/roles/dashboards_upgrade/tasks/main.yml
@@ -50,6 +50,14 @@
src: /usr/share/percona-dashboards/panels/
dest: /srv/grafana/plugins/
+- name: Set permissions for the plugin directory
+ file:
+ path: "/srv/grafana/plugins"
+ state: directory
+ owner: grafana
+ group: grafana
+ mode: "0775"
+
- name: Check that the SQLite grafana database exists
stat:
path: /srv/grafana/grafana.db
diff --git a/update/ansible/playbook/tasks/roles/grafana/files/grafana.ini b/update/ansible/playbook/tasks/roles/grafana/files/grafana.ini
index 73a6ed90e7..10318273f2 100644
--- a/update/ansible/playbook/tasks/roles/grafana/files/grafana.ini
+++ b/update/ansible/playbook/tasks/roles/grafana/files/grafana.ini
@@ -1,14 +1,42 @@
##################### Grafana Configuration #####################
# Only changed settings. You can find default settings in /usr/share/grafana/conf/defaults.ini
+#################################### Database ####################################
+[database]
+# You can configure the database connection by specifying type, host, name, user and password
+# as separate properties or as on string using the url properties.
+
+# Either "mysql", "postgres" or "sqlite3", it's your choice
+type = postgres
+host = localhost
+user = grafana
+# If the password contains # or ; you have to wrap it with triple quotes. Ex """#password;"""
+password = grafana
+
[paths]
# Directory where grafana will automatically scan and look for plugins
plugins = /srv/grafana/plugins
+# Directory where grafana can store logs
+logs = /srv/logs
+# Path to where grafana can store temp files, sessions, and the sqlite3 db (if that is used)
+data = /srv/grafana
+
+#################################### Logging ##########################
+[log]
+# Either "console", "file", "syslog". Default is console and file
+mode = console
+
+# For "console" mode only
+[log.console]
+# log line format, valid options are text, console and json
+format = console
#################################### Server ####################################
[server]
# enable gzip
enable_gzip = true
+# The full public facing url
+root_url = https://%(domain)s/graph
#################################### Snapshots ###########################
[snapshots]
diff --git a/update/ansible/playbook/tasks/roles/grafana/tasks/main.yml b/update/ansible/playbook/tasks/roles/grafana/tasks/main.yml
index cce395aa28..e212ed109d 100644
--- a/update/ansible/playbook/tasks/roles/grafana/tasks/main.yml
+++ b/update/ansible/playbook/tasks/roles/grafana/tasks/main.yml
@@ -5,7 +5,7 @@
state: directory
owner: grafana
group: grafana
- mode: '0775'
+ mode: "0775"
loop:
- /srv/grafana
- /srv/grafana/plugins
@@ -13,7 +13,7 @@
- name: Set Grafana folder for plugins on /srv partition for all users
lineinfile:
path: /etc/bashrc
- line: 'export GF_PLUGIN_DIR=/srv/grafana/plugins'
+ line: "export GF_PLUGIN_DIR=/srv/grafana/plugins"
- name: Copy new version of grafana.ini
copy:
@@ -21,7 +21,43 @@
dest: /etc/grafana/grafana.ini
owner: grafana
group: grafana
- mode: '0444'
+ mode: "0444"
+
+- name: Check that the SQLite grafana database exists
+ stat:
+ path: /srv/grafana/grafana.db
+ register: sqlite_grafana
+
+- name: Temporary change database to SQLite
+ block:
+ - name: Remove database options (SQLite is default)
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: type
+ state: absent
+
+ - name: Remove database host
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: host
+ state: absent
+
+ - name: Remove database user
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: user
+ state: absent
+
+ - name: Remove database password
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: password
+ state: absent
+ when: sqlite_grafana.stat.exists
- name: Create provisioning directory
file:
@@ -46,5 +82,5 @@
- dashboards
- name: Upgrade grafana database (Get the latest schema)
- command: grafana-cli --homepath=/usr/share/grafana admin data-migration encrypt-datasource-passwords
+ command: grafana cli --homepath=/usr/share/grafana admin data-migration encrypt-datasource-passwords
changed_when: True
diff --git a/update/ansible/playbook/tasks/roles/initialization/tasks/main.yml b/update/ansible/playbook/tasks/roles/initialization/tasks/main.yml
index 7957b96ee6..2476b13d68 100644
--- a/update/ansible/playbook/tasks/roles/initialization/tasks/main.yml
+++ b/update/ansible/playbook/tasks/roles/initialization/tasks/main.yml
@@ -1,21 +1,9 @@
---
# This role contains tasks executed during initialization of PMM Server
-
-# PMM-10858 - In certain environments, including AWS EC2, some of the
-# EPEL repository mirrors do not respond within the time limit defined
-# by pmm-update which is currently set to 30 seconds. This was causing
-# supervisord to kill pmm-update-checker
-- name: Update repository settings
- when:
- - ansible_distribution == "CentOS"
- - ansible_distribution_major_version == "7"
- command: yum-config-manager --setopt=epel.timeout=1 --save
- changed_when: True
-
-- name: Clean yum metadata
- command: yum clean metadata
- become: true
- changed_when: True
+- name: Determine type of upgrade
+ set_fact:
+ ui_upgrade: False
+ when: ui_upgrade is undefined
- name: Get current version
slurp:
@@ -46,6 +34,32 @@
debug:
msg: "Current version: {{ pmm_current_version }} Image Version: {{ pmm_image_version }}"
+
+# We use current_version_file['failed'] because we don't want to run this on creating container
+# and we use pmm_current_version is version(pmm_image_version, '>=') to run it only if upgrade is required
+- name: Enable maintenance mode only for docker upgrade
+ copy:
+ src: maintenance.html
+ dest: /usr/share/pmm-server/maintenance/
+ mode: 0644
+ when: not ui_upgrade and current_version_file['failed'] == false and not pmm_current_version is version(pmm_image_version, '>=')
+
+# PMM-10858 - In certain environments, including AWS EC2, some of the
+# EPEL repository mirrors do not respond within the time limit defined
+# by pmm-update which is currently set to 30 seconds. This was causing
+# supervisord to kill pmm-update-checker
+- name: Update repository settings
+ when:
+ - ansible_distribution == "CentOS"
+ - ansible_distribution_major_version == "7"
+ command: yum-config-manager --setopt=epel.timeout=1 --save
+ changed_when: True
+
+- name: Clean yum metadata
+ command: yum clean metadata
+ become: true
+ changed_when: True
+
- name: Check if we need an update or not
include_role:
name: dashboards_upgrade
@@ -65,3 +79,100 @@
include_role:
name: postgres
when: is_postgres_11.stat.exists
+
+- name: Create grafana database in postgres
+ postgresql_db:
+ name: grafana
+ state: present
+
+- name: Create grafana user in postgres
+ postgresql_user:
+ db: grafana
+ name: grafana
+ password: grafana
+ priv: 'ALL'
+ expires: infinity
+ state: present
+ when: not ansible_check_mode
+
+- name: Create working directory for Alertmanager
+ file: path=/srv/alertmanager/data state=directory owner=pmm group=pmm
+
+- name: Create working directory for VictoriaMetrics
+ file: path=/srv/victoriametrics/data state=directory owner=pmm group=pmm
+
+- name: Create empty configuration file for VictoriaMetrics
+ file: path=/etc/victoriametrics-promscrape.yml state=touch owner=pmm group=pmm
+
+- name: Run SQLite -> Postgres only for docker upgrade
+ block:
+ - name: Check that the SQLite grafana database exists
+ stat:
+ path: /srv/grafana/grafana.db
+ register: is_database_sqlite
+
+ - name: Temporary change database to SQLite
+ block:
+ - name: Remove database options (SQLite is default)
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: type
+ state: absent
+
+ - name: Remove database host
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: host
+ state: absent
+
+ - name: Remove database user
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: user
+ state: absent
+
+ - name: Remove database password
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: password
+ state: absent
+
+ - name: Upgrade grafana database (Get the latest schema)
+ command: grafana cli --homepath=/usr/share/grafana admin data-migration encrypt-datasource-passwords
+ changed_when: True
+
+ - name: Start grafana again
+ supervisorctl:
+ name: grafana
+ state: restarted
+
+ - name: Wait for grafana
+ pause: seconds=10
+
+ - name: Migrate Grafana database from SQLite to Postgresql
+ include_role:
+ name: sqlite-to-postgres
+ tags:
+ - skip_ansible_lint # '503 Tasks that run when changed should likely be handlers'.
+ when: is_database_sqlite.stat.exists
+
+ - name: Wait for PMM to be ready
+ ansible.builtin.uri:
+ url: "http://127.0.0.1:7772/v1/readyz"
+ status_code: 200
+ method: GET
+ retries: 120
+ delay: 1
+
+ - name: Disable maintenance mode
+ file:
+ state: absent
+ path: /usr/share/pmm-server/maintenance/maintenance.html
+ # We use current_version_file['failed'] because we don't want to run this on creating container
+ when: not ui_upgrade and current_version_file['failed'] == false and not pmm_current_version is version(pmm_image_version, '>=')
+
+
diff --git a/update/ansible/playbook/tasks/roles/nginx/files/conf.d/pmm.conf b/update/ansible/playbook/tasks/roles/nginx/files/conf.d/pmm.conf
index 4b136d2ce3..dfdbfe8f11 100644
--- a/update/ansible/playbook/tasks/roles/nginx/files/conf.d/pmm.conf
+++ b/update/ansible/playbook/tasks/roles/nginx/files/conf.d/pmm.conf
@@ -43,6 +43,29 @@
ssl_trusted_certificate /srv/nginx/ca-certs.pem;
ssl_dhparam /srv/nginx/dhparam.pem;
+ # this block checks for maintenance.html file and, if it exists, it redirects all requests to the maintenance page
+ # there are two exceptions for it /v1/Updates/Status and /auth_request endpoints
+ set $maintenance_mode 0;
+
+ if (-f /usr/share/pmm-server/maintenance/maintenance.html) {
+ set $maintenance_mode 1;
+ }
+
+ if ($request_uri ~* "^/v1/Updates/Status|^/auth_request") {
+ set $maintenance_mode 0;
+ }
+
+ if ($maintenance_mode = 1) {
+ return 503;
+ }
+
+ error_page 503 @maintenance;
+
+ location @maintenance {
+ root /usr/share/pmm-server/maintenance;
+ rewrite ^(.*)$ /maintenance.html break;
+ }
+
# Enable passing of the remote user's IP address to all
# proxied services using the X-Forwarded-For header
diff --git a/update/ansible/playbook/tasks/roles/sqlite-to-postgres/tasks/main.yml b/update/ansible/playbook/tasks/roles/sqlite-to-postgres/tasks/main.yml
new file mode 100644
index 0000000000..490ce26c7f
--- /dev/null
+++ b/update/ansible/playbook/tasks/roles/sqlite-to-postgres/tasks/main.yml
@@ -0,0 +1,132 @@
+---
+- name: Wait for grafana to update DB and be ready
+ ansible.builtin.uri:
+ url: "http://127.0.0.1:3000/api/health"
+ status_code: 200
+ method: GET
+ register: healthcheck
+ until: healthcheck is not failed
+ retries: 120
+ delay: 1
+
+- name: Create Grafana backup dir
+ file:
+ path: "/srv/backup/grafana"
+ state: directory
+ owner: grafana
+ group: grafana
+ mode: '0700'
+
+- name: Stop grafana before upgrade
+ supervisorctl:
+ name: 'grafana'
+ state: stopped
+
+- name: Create backup for SQLite Grafana database
+ copy:
+ src: /srv/grafana/grafana.db
+ dest: "/srv/backup/grafana/grafana.db"
+ owner: grafana
+ group: grafana
+ mode: '0700'
+
+- name: Remove all ` symbols in grafana dashboard description
+ command: sqlite3 /srv/grafana/grafana.db -cmd ".timeout 60000" "UPDATE dashboard SET data = REPLACE(data, '`', '');"
+ changed_when: True
+
+- name: Disable provisioning before change database
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: paths
+ option: provisioning
+ value: conf/provisioning_disable
+
+- name: Switch to postgres
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: type
+ value: postgres
+
+- name: Set database host
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: host
+ value: localhost
+
+- name: Set database user
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: user
+ value: grafana
+
+- name: Set database password
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: database
+ option: password
+ value: grafana
+
+- name: Start grafana again
+ supervisorctl:
+ name: grafana
+ state: restarted
+ ignore_errors: yes
+
+- name: Check if initial data were created
+ postgresql_query:
+ db: grafana
+ query: SELECT 1 FROM org WHERE id=1
+ retries: 3
+ delay: 3
+ register: psql_result
+ until: psql_result.rowcount == 1
+ when: not ansible_check_mode
+
+- name: Wait for grafana database initialization
+ pause:
+ seconds: 10
+
+- name: Stop grafana before upgrade
+ supervisorctl:
+ name: grafana
+ state: stopped
+
+- name: Remove default admin user
+ postgresql_query:
+ db: grafana
+ query: DELETE FROM public.user WHERE login='admin'
+ when: not ansible_check_mode
+
+- name: Run grafana migrator
+ command: grafana-db-migrator --change-char-to-text /srv/grafana/grafana.db "postgres://grafana:grafana@localhost:5432/grafana?sslmode=disable"
+ register: migrator_output
+ changed_when: "'All done' in migrator_output.stdout"
+
+- name: Enable provisioning after change database
+ ini_file:
+ dest: /etc/grafana/grafana.ini
+ section: paths
+ option: provisioning
+ value: conf/provisioning
+
+- name: Start grafana again
+ supervisorctl:
+ name: grafana
+ state: restarted
+
+- name: Wait for grafana initialization
+ pause:
+ seconds: 5
+
+- name: Fix database/folder relationship
+ command: grafana-db-migrator --fix-folders-id /srv/grafana/grafana.db "postgres://grafana:grafana@localhost:5432/grafana?sslmode=disable"
+ register: migrator_output
+ changed_when: "'All done' in migrator_output.stdout"
+
+- name: Remove SQLite Grafana database
+ file:
+ path: /srv/grafana/grafana.db
+ state: absent
diff --git a/update/ansible/playbook/tasks/update.yml b/update/ansible/playbook/tasks/update.yml
index 48432dd482..61ae3a43a2 100644
--- a/update/ansible/playbook/tasks/update.yml
+++ b/update/ansible/playbook/tasks/update.yml
@@ -20,6 +20,7 @@
- pmm2-client
- pmm-dump
- vmproxy
+ - grafana-db-migrator
pre_tasks:
- name: detect /srv/pmm-distribution
stat:
@@ -38,12 +39,24 @@
is_docker: True
when: is_docker is undefined
tasks:
- # we need install this package here because it contain VERSION file
+ - name: Enable maintenance mode
+ copy:
+ src: maintenance.html
+ dest: /usr/share/pmm-server/maintenance/
+ mode: 0644
+
- name: Remove percona-dashboard without architecture
yum:
name: percona-dashboards.*noarch
state: absent
+ # see https://jira.percona.com/browse/PMM-8492 for details about a issue
+ - name: Delete experimental repo file in 2.16 version
+ file:
+ path: "/etc/yum.repos.d/percona-original-experimental.repo"
+ state: absent
+ register: experimental_repo_existed
+
- name: Update percona-dashboards package
yum:
name:
@@ -51,6 +64,34 @@
- percona-grafana
state: latest
+ - name: Cleanup yum metadata
+ command: yum clean metadata
+ register: yum_clean_result
+ changed_when: "'Cleaning repos' in yum_clean_result.stdout"
+ when: experimental_repo_existed.changed
+ tags:
+ - skip_ansible_lint # '503 Tasks that run when changed should likely be handlers'.
+ # The handler looks bad in this case
+
+ # TODO: join with the command above
+ - name: Cleanup yum metadata
+ command: yum clean metadata
+ become: true
+ tags:
+ - skip_ansible_lint
+
+ # Split download and update to produce a bit more of progress output.
+ - name: Download pmm2 packages
+ yum:
+ name: "{{ pmm_packages }}"
+ state: latest
+ download_only: yes
+
+ - name: Update pmm2 packages
+ yum:
+ name: "{{ pmm_packages }}"
+ state: latest
+
- name: Create supervisord dir
file:
path: /etc/supervisord.d/
@@ -61,27 +102,12 @@
src: pmm.ini
dest: /etc/supervisord.d/pmm.ini
+ # restart pmm-managed-init and pmm-managed first as they may update supervisord configuration on start
- name: Generate new supervisor config
command: pmm-managed-init
register: managed_init_result
changed_when: True
- - name: Update postgresql version_1
- command: sed -i 's:-D /srv/postgres$:-D /srv/postgres14:' /etc/supervisord.d/pmm.ini
- changed_when: true
-
- - name: Update postgresql version_2
- command: sed -i 's:/usr/pgsql/bin/postgres:/usr/pgsql-14/bin/postgres:' /etc/supervisord.d/pmm.ini
- changed_when: true
-
- - name: Update postgresql version_3
- command: sed -i 's:/srv/logs/postgresql.log:/srv/logs/postgresql14.log:' /etc/supervisord.d/pmm.ini
- changed_when: true
-
- - name: Update postgresql version_4
- command: sed -i 's:/usr/pgsql-11/bin/postgres:/usr/pgsql-14/bin/postgres:' /etc/supervisord.d/pmm.ini
- changed_when: true
-
- name: Disable pmm-update-perform-init
ini_file:
path: /etc/supervisord.d/pmm.ini
@@ -149,9 +175,16 @@
when: is_docker and not is_supervisor_running.stat.exists and (ansible_distribution == 'OracleLinux' or ansible_distribution == 'AlmaLinux') and ansible_distribution_major_version == '9'
shell: /usr/local/bin/supervisord -c /etc/supervisord.conf &
+ - name: Wait until postgres port is present before continuing
+ wait_for:
+ host: localhost
+ port: 5432
+
- name: Run initialization playbook
include_role:
name: initialization
+ vars:
+ ui_upgrade: True
- name: Enable crond service
when: not is_docker
@@ -187,48 +220,6 @@
- name: Check reread results
debug: var=reread_result.stdout_lines
- # see https://jira.percona.com/browse/PMM-8492 for details about a issue
- - name: Delete experimental repo file in 2.16 version
- file:
- path: "/etc/yum.repos.d/percona-original-experimental.repo"
- state: absent
- register: experimental_repo_existed
-
- - name: Cleanup yum metadata
- command: yum clean metadata
- register: yum_clean_result
- changed_when: "'Cleaning repos' in yum_clean_result.stdout"
- when: experimental_repo_existed.changed
- tags:
- - skip_ansible_lint # '503 Tasks that run when changed should likely be handlers'.
- # The handler looks bad in this case
-
- # TODO: join with the command above
- - name: Cleanup yum metadata
- command: yum clean metadata
- become: true
- tags:
- - skip_ansible_lint
-
- # Split download and update to produce a bit more of progress output.
- - name: Download pmm2 packages
- yum:
- name: "{{ pmm_packages }}"
- state: latest
- download_only: yes
-
- - name: Update pmm2 packages
- yum:
- name: "{{ pmm_packages }}"
- state: latest
-
-
- # restart pmm-managed-init and pmm-managed first as they may update supervisord configuration on start
- - name: Generate new supervisor config
- command: pmm-managed-init
- register: managed_init_result
- changed_when: True
-
- name: Restart pmm-managed EL7
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'
command: supervisorctl {{ item }} pmm-managed
@@ -246,9 +237,12 @@
# give pmm-managed time to update supervisord configuration,
# and give update UI time to catch up after pmm-managed restart
- name: Wait for pmm-managed
- pause: seconds=5
+ pause: seconds=10
- - name: Update system packages
+ - name: Update system packages EL7
+ when:
+ - ansible_distribution == "CentOS"
+ - ansible_distribution_major_version == "7"
yum:
name: "*"
state: latest
@@ -256,7 +250,10 @@
exclude:
- nginx*
- - name: Updating only select packages
+ - name: Updating only select packages EL7
+ when:
+ - ansible_distribution == "CentOS"
+ - ansible_distribution_major_version == "7"
yum:
name: "{{ item }}"
state: latest
@@ -267,6 +264,38 @@
- sshpass
- vi
+ - name: Remove ansible RPM if installed | EL9
+ when:
+ - ansible_distribution == 'OracleLinux' or ansible_distribution == 'AlmaLinux'
+ - ansible_distribution_major_version == '9'
+ yum:
+ name: ansible
+ state: absent
+ ignore_errors: yes
+
+ - name: Install ansible-core RPM | EL9
+ when:
+ - ansible_distribution == 'OracleLinux' or ansible_distribution == 'AlmaLinux'
+ - ansible_distribution_major_version == '9'
+ yum:
+ name:
+ - ansible-core
+ - ansible-collection-community-general
+ - ansible-collection-community-postgresql
+ - ansible-collection-ansible-posix
+ state: present
+
+ - name: Update system packages EL9
+ when:
+ - ansible_distribution == 'OracleLinux' or ansible_distribution == 'AlmaLinux'
+ - ansible_distribution_major_version == '9'
+ - not ansible_check_mode
+ yum:
+ name: "*"
+ state: latest
+ exclude:
+ - nginx*
+
- name: Install nginx
include_role:
name: nginx
@@ -284,17 +313,6 @@
enabled: no
when: not is_docker
- - name: Remove old or redundant packages
- yum:
- state: absent
- name:
- - percona-qan-app # https://jira.percona.com/browse/PMM-6766
- - mariadb-libs # https://jira.percona.com/browse/PMM-5215
- - logrotate # https://jira.percona.com/browse/PMM-7627
- - pmm-server # https://jira.percona.com/browse/PMM-11239
- - screen
- - yum-cron
-
# https://jira.percona.com/browse/PMM-9298
- name: Copy rezise-xfs file for lvm
copy:
@@ -317,19 +335,6 @@
regexp: "set -o errexit"
replace: ""
- # TODO: Create /srv/alertmanager/data and /srv/victoriametrics/data in pmm-managed
- # to support Docker-way (swap image) updates.
- # https://jira.percona.com/browse/PMM-7024
-
- - name: Create working directory for Alertmanager
- file: path=/srv/alertmanager/data state=directory owner=pmm group=pmm
-
- - name: Create working directory for VictoriaMetrics
- file: path=/srv/victoriametrics/data state=directory owner=pmm group=pmm
-
- - name: Create empty configuration file for VictoriaMetrics
- file: path=/etc/victoriametrics-promscrape.yml state=touch owner=pmm group=pmm
-
- name: Reread supervisord configuration again EL7
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'
command: supervisorctl reread
@@ -381,12 +386,46 @@
- /etc/yum/yum-cron-hourly.conf
- /etc/yum/yum-cron.conf
- - name: Enable pmm-update-perform-init after build
- ini_file:
- path: /etc/supervisord.d/pmm.ini
- section: program:pmm-update-perform-init
- option: autostart
- value: "true"
+ - name: Check that the SQLite grafana database exists
+ stat:
+ path: /srv/grafana/grafana.db
+ register: is_database_sqlite
+
+ - name: Migrate Grafana database from SQLite to Postgresql
+ include_role:
+ name: sqlite-to-postgres
+ when: is_database_sqlite.stat.exists
+ tags:
+ - skip_ansible_lint # '503 Tasks that run when changed should likely be handlers'.
+
+ - name: Fix grafana fields type
+ postgresql_query:
+ db: grafana
+ query: "{{ item }}"
+ loop:
+ - ALTER TABLE tag ALTER COLUMN key TYPE text;
+ - ALTER TABLE tag ALTER COLUMN value TYPE text;
+ - ALTER TABLE api_key ALTER COLUMN key TYPE text;
+ - ALTER TABLE api_key ALTER COLUMN name TYPE text;
+ when: not ansible_check_mode
+
+ # we need to put this step as one of the last steps, because it removes pmm.ini and /etc/alertmanager.yml
+ - name: Remove old or redundant packages
+ yum:
+ state: absent
+ name:
+ - percona-qan-app # https://jira.percona.com/browse/PMM-6766
+ - mariadb-libs # https://jira.percona.com/browse/PMM-5215
+ - logrotate # https://jira.percona.com/browse/PMM-7627
+ - pmm-server # https://jira.percona.com/browse/PMM-11239
+ - screen
+ - yum-cron
+
+ # Regenerating pmm.ini and enabling pmm-update-perform-init
+ - name: Generate new supervisor config
+ command: pmm-managed-init
+ register: managed_init_result
+ changed_when: True
- name: Reread pmm-update-perform-init supervisor config EL7
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'
@@ -400,6 +439,21 @@
register: reread_init__result
changed_when: "'No config updates to processes' not in reread_init__result.stdout"
+ # restarting pmm-managed to regenerate /etc/alertmanager.yml
+ - name: Restart pmm-managed EL7
+ when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'
+ command: supervisorctl {{ item }} pmm-managed
+ become: true
+ changed_when: true
+ with_items: ["stop", "remove", "add"]
+
+ - name: Restart pmm-managed EL9
+ when: (ansible_distribution == 'OracleLinux' or ansible_distribution == 'AlmaLinux') and ansible_distribution_major_version == '9'
+ command: /usr/local/bin/supervisorctl {{ item }} pmm-managed
+ become: true
+ changed_when: true
+ with_items: ["stop", "remove", "add"]
+
- name: Update/restart other services EL7
when: ansible_distribution == 'CentOS' and ansible_distribution_major_version == '7'
command: supervisorctl update
@@ -415,6 +469,16 @@
- name: Print other services's logs
debug: var=update_result.stdout_lines
+ - name: Wait for PMM to be ready
+ ansible.builtin.uri:
+ url: "http://127.0.0.1:7772/v1/readyz"
+ status_code: 200
+ method: GET
+ register: healthcheck
+ until: healthcheck is not failed
+ retries: 120
+ delay: 1
+
# SIGUSR2 is sent to supervisord by pmm-managed right before the update for logging to work correctly.
# We use that fact to show what was restarted during the update.
- name: Get supervisord logs EL7
@@ -432,7 +496,14 @@
- name: Print supervisord logs
debug: var=maintail_result.stdout_lines
+ - name: Disable maintenance mode
+ file:
+ state: absent
+ path: /usr/share/pmm-server/maintenance/maintenance.html
+
- name: Cleanup yum cache
file:
state: absent
path: /var/cache/yum
+
+
diff --git a/update/docker-compose.yml b/update/docker-compose.yml
index 5be6dd1cbf..2bf87f6d11 100644
--- a/update/docker-compose.yml
+++ b/update/docker-compose.yml
@@ -6,7 +6,7 @@ services:
environment:
# for tests
- PMM_SERVER_IMAGE=${PMM_SERVER_IMAGE:-percona/pmm-server:2}
- - GO_VERSION=${GO_VERSION:-1.20.x}
+ - GO_VERSION=${GO_VERSION:-1.21.x}
- PATH=/root/go/bin:$PATH
- REVIEWDOG_GITHUB_API_TOKEN=${REVIEWDOG_GITHUB_API_TOKEN}
volumes:
diff --git a/update/main.go b/update/main.go
index 01c71fa3ad..e1f87f921c 100644
--- a/update/main.go
+++ b/update/main.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/main_test.go b/update/main_test.go
index 5731973001..98a41a6c14 100644
--- a/update/main_test.go
+++ b/update/main_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/maincover_test.go b/update/maincover_test.go
index 921c29afbf..aa26b16d85 100644
--- a/update/maincover_test.go
+++ b/update/maincover_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/pkg/ansible/ansible.go b/update/pkg/ansible/ansible.go
index 00889e47bb..08c1d05547 100644
--- a/update/pkg/ansible/ansible.go
+++ b/update/pkg/ansible/ansible.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/pkg/ansible/ansible_test.go b/update/pkg/ansible/ansible_test.go
index a98f8d41c4..6f4e34eb20 100644
--- a/update/pkg/ansible/ansible_test.go
+++ b/update/pkg/ansible/ansible_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/pkg/run/run.go b/update/pkg/run/run.go
index b370d24963..399a903273 100644
--- a/update/pkg/run/run.go
+++ b/update/pkg/run/run.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/pkg/run/run_test.go b/update/pkg/run/run_test.go
index 1f73d825a8..8557880ab8 100644
--- a/update/pkg/run/run_test.go
+++ b/update/pkg/run/run_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/pkg/yum/info.go b/update/pkg/yum/info.go
index f705d2922e..95728e928d 100644
--- a/update/pkg/yum/info.go
+++ b/update/pkg/yum/info.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/pkg/yum/info_test.go b/update/pkg/yum/info_test.go
index d8cc827c80..1604e92d1d 100644
--- a/update/pkg/yum/info_test.go
+++ b/update/pkg/yum/info_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/pkg/yum/yum.go b/update/pkg/yum/yum.go
index f9b906f86d..008ad208b1 100644
--- a/update/pkg/yum/yum.go
+++ b/update/pkg/yum/yum.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/update/pkg/yum/yum_test.go b/update/pkg/yum/yum_test.go
index 5b3e70131a..d2ad230000 100644
--- a/update/pkg/yum/yum_test.go
+++ b/update/pkg/yum/yum_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/utils/depstests/depstests.go b/utils/depstests/depstests.go
index 67fa07dda4..f7b17754f1 100644
--- a/utils/depstests/depstests.go
+++ b/utils/depstests/depstests.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/utils/depstests/protobuf_test.go b/utils/depstests/protobuf_test.go
index 788c5ecbcc..941aa6f7f8 100644
--- a/utils/depstests/protobuf_test.go
+++ b/utils/depstests/protobuf_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/utils/errors/errors.go b/utils/errors/errors.go
index 1924f38d88..1499d84778 100644
--- a/utils/errors/errors.go
+++ b/utils/errors/errors.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -15,7 +15,7 @@
// Package errors contains a custom HTTP error handler that adds an extra `Error` field to error payloads.
// This helps us maintain compatibility with older PMM clients while keeping the benefits of grpc-gateway v2.
-// Our requirement is fairly minimal, but copy a lot of code from grpc-gateway to account for unexported fields and methods
+// Our requirement is fairly minimal, but copy a lot of code from grpc-gateway to account for unexported fields and methods.
package errors
import (
@@ -37,7 +37,7 @@ import (
// PMMHTTPErrorHandler is a custom implementation of DefaultHTTPErrorHandler
// (https://github.com/grpc-ecosystem/grpc-gateway/blob/aec6aa29864109e41408491319a859f190ec4040/runtime/errors.go#L93)
-// It injects an extra `Error` field in error responses to support old PMM clients
+// It injects an extra `Error` field in error responses to support old PMM clients.
func PMMHTTPErrorHandler(ctx context.Context, mux *runtime.ServeMux, marshaler runtime.Marshaler, w http.ResponseWriter, r *http.Request, err error) {
// return Internal when Marshal failed
const fallback = `{"code": 13, "message": "failed to marshal error message"}`
diff --git a/managed/utils/logger/global.go b/utils/logger/global.go
similarity index 88%
rename from managed/utils/logger/global.go
rename to utils/logger/global.go
index 2d9a50c7c2..9368bb145c 100644
--- a/managed/utils/logger/global.go
+++ b/utils/logger/global.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -24,11 +24,9 @@ import (
)
// SetupGlobalLogger configures logrus.StandardLogger() to enable multiline-friendly formatter
-// in both development (with terminal) and production (without terminal).
+// in both development (with terminal) and production (without terminal) with default prettyfier.
func SetupGlobalLogger() {
logrus.SetFormatter(&logrus.TextFormatter{
- // https://github.com/sirupsen/logrus/blob/839c75faf7f98a33d445d181f3018b5c3409a45e/text_formatter.go#L176-L178
- ForceColors: true,
FullTimestamp: true,
TimestampFormat: "2006-01-02T15:04:05.000-07:00",
diff --git a/managed/utils/logger/grpc.go b/utils/logger/grpc.go
similarity index 96%
rename from managed/utils/logger/grpc.go
rename to utils/logger/grpc.go
index 15c761c217..fcc4f2219e 100644
--- a/managed/utils/logger/grpc.go
+++ b/utils/logger/grpc.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -38,7 +38,7 @@ func (v *GRPC) Info(args ...interface{}) { v.Trace(args...) }
func (v *GRPC) Infoln(args ...interface{}) { v.Traceln(args...) }
func (v *GRPC) Infof(format string, args ...interface{}) { v.Tracef(format, args...) }
-// check interfaces
+// check interfaces.
var (
_ grpclog.LoggerV2 = (*GRPC)(nil)
)
diff --git a/managed/utils/logger/logger.go b/utils/logger/logger.go
similarity index 96%
rename from managed/utils/logger/logger.go
rename to utils/logger/logger.go
index b47b60f28e..89a0211ad1 100644
--- a/managed/utils/logger/logger.go
+++ b/utils/logger/logger.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2017 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -23,7 +23,7 @@ import (
"github.com/sirupsen/logrus"
)
-// key is unexported to prevent collisions - it is different from any other type in other packages
+// key is unexported to prevent collisions - it is different from any other type in other packages.
type key struct{}
// Get returns logrus entry for given context. Set must be called before this method is called.
diff --git a/utils/nodeinfo/nodeinfo.go b/utils/nodeinfo/nodeinfo.go
index 5e0ac2539d..f8f928bf89 100644
--- a/utils/nodeinfo/nodeinfo.go
+++ b/utils/nodeinfo/nodeinfo.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -68,7 +68,7 @@ func readMachineID() string {
return ""
}
-// TODO remove that completely once we have "zero port" feature
+// TODO remove that completely once we have "zero port" feature.
func readPublicAddress() string {
var res string
diff --git a/utils/nodeinfo/nodeinfo_test.go b/utils/nodeinfo/nodeinfo_test.go
index 159b824116..ea97b4b761 100644
--- a/utils/nodeinfo/nodeinfo_test.go
+++ b/utils/nodeinfo/nodeinfo_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/utils/pdeathsig/pdeathsig.go b/utils/pdeathsig/pdeathsig.go
index 28d33fbbbf..cf31b6ee32 100644
--- a/utils/pdeathsig/pdeathsig.go
+++ b/utils/pdeathsig/pdeathsig.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/utils/pdeathsig/pdeathsig_linux.go b/utils/pdeathsig/pdeathsig_linux.go
index 1738028d05..87ecf654a1 100644
--- a/utils/pdeathsig/pdeathsig_linux.go
+++ b/utils/pdeathsig/pdeathsig_linux.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/utils/sqlmetrics/reform.go b/utils/sqlmetrics/reform.go
index 843ffced74..c7d8577140 100644
--- a/utils/sqlmetrics/reform.go
+++ b/utils/sqlmetrics/reform.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/utils/sqlmetrics/sqlmetrics.go b/utils/sqlmetrics/sqlmetrics.go
index 9404cb91c4..00a582ef4d 100644
--- a/utils/sqlmetrics/sqlmetrics.go
+++ b/utils/sqlmetrics/sqlmetrics.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -137,7 +137,7 @@ func (c *Collector) Collect(ch chan<- prom.Metric) {
float64(stats.MaxLifetimeClosed))
}
-// check interfaces
+// check interfaces.
var (
_ prom.Collector = (*Collector)(nil)
)
diff --git a/utils/sqlrows/sqlrows.go b/utils/sqlrows/sqlrows.go
index 7255f427c0..35f72a55e0 100644
--- a/utils/sqlrows/sqlrows.go
+++ b/utils/sqlrows/sqlrows.go
@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-// Package sqlrows provides helper methods for *sql.Rows
+// Package sqlrows provides helper methods for *sql.Rows.
package sqlrows
import "database/sql"
diff --git a/utils/tlsconfig/tlsconfig.go b/utils/tlsconfig/tlsconfig.go
index 29e101e3b1..e527cc6371 100644
--- a/utils/tlsconfig/tlsconfig.go
+++ b/utils/tlsconfig/tlsconfig.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/version/parsed.go b/version/parsed.go
index c312272d52..dce3d6887d 100644
--- a/version/parsed.go
+++ b/version/parsed.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/version/parsed_test.go b/version/parsed_test.go
index c049811b19..cba04bd74a 100644
--- a/version/parsed_test.go
+++ b/version/parsed_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/version/release.go b/version/release.go
index 1560e45a5d..e35ce12602 100644
--- a/version/release.go
+++ b/version/release.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -71,7 +71,7 @@ func Time() (time.Time, error) {
return time.Unix(sec, 0).UTC(), nil
}
-// timestampFormatted returns timestamp in format "YYYY-MM-DD HH:mm:ss (UTC)"
+// timestampFormatted returns timestamp in format "YYYY-MM-DD HH:mm:ss (UTC)".
func timestampFormatted() string {
timestamp := Timestamp
if t, err := Time(); err == nil {
diff --git a/version/release_test.go b/version/release_test.go
index 019668c407..46db728e84 100644
--- a/version/release_test.go
+++ b/version/release_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/version/update.go b/version/update.go
index 165b712cf3..5441043343 100644
--- a/version/update.go
+++ b/version/update.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2019 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/vmproxy/Makefile b/vmproxy/Makefile
index 458aea2543..de22f04d71 100644
--- a/vmproxy/Makefile
+++ b/vmproxy/Makefile
@@ -16,7 +16,7 @@ ifeq ($(GOBIN),)
endif
LD_FLAGS = -ldflags " \
- -X 'github.com/percona/pmm/version.ProjectName=pmm-admin' \
+ -X 'github.com/percona/pmm/version.ProjectName=vmproxy' \
-X 'github.com/percona/pmm/version.Version=$(PMM_RELEASE_VERSION)' \
-X 'github.com/percona/pmm/version.PMMVersion=$(PMM_RELEASE_VERSION)' \
-X 'github.com/percona/pmm/version.Timestamp=$(PMM_RELEASE_TIMESTAMP)' \
diff --git a/vmproxy/main.go b/vmproxy/main.go
index a955dbf4a4..f52ed527f4 100644
--- a/vmproxy/main.go
+++ b/vmproxy/main.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/vmproxy/main_test.go b/vmproxy/main_test.go
index c4d72f4287..8b003d232b 100644
--- a/vmproxy/main_test.go
+++ b/vmproxy/main_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
diff --git a/vmproxy/proxy/proxy.go b/vmproxy/proxy/proxy.go
index 8fcb9e6683..dbc1aa0730 100644
--- a/vmproxy/proxy/proxy.go
+++ b/vmproxy/proxy/proxy.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
@@ -13,7 +13,7 @@
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see .
-// Package proxy provides http reverse proxy functionality
+// Package proxy provides http reverse proxy functionality.
package proxy
import (
@@ -24,13 +24,14 @@ import (
"net/http"
"net/http/httputil"
"net/url"
+ "strings"
"time"
"github.com/pkg/errors"
"github.com/sirupsen/logrus"
)
-// Config defines options for starting proxy
+// Config defines options for starting proxy.
type Config struct {
// Name of the header to check for filters. Case insensitive.
HeaderName string
@@ -84,6 +85,12 @@ func director(target *url.URL, headerName string) func(*http.Request) {
req.URL.Scheme = target.Scheme
req.URL.Host = target.Host
+ rp, err := target.Parse(strings.TrimPrefix(req.URL.Path, "/"))
+ if err != nil {
+ logrus.Error(err)
+ }
+ req.URL.Path = rp.Path
+
// Replace extra filters if present
if filters := req.Header.Get(headerName); filters != "" {
q := req.URL.Query()
diff --git a/vmproxy/proxy/proxy_test.go b/vmproxy/proxy/proxy_test.go
index 6a5008ea8c..daa35dbd5b 100644
--- a/vmproxy/proxy/proxy_test.go
+++ b/vmproxy/proxy/proxy_test.go
@@ -1,4 +1,4 @@
-// Copyright (C) 2022 Percona LLC
+// Copyright (C) 2023 Percona LLC
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by