Defines the controller api metrics and registers them at controller startup (#1917)

Co-authored-by: Hugo Vieira <hugoamvieira@users.noreply.github.com>
This commit is contained in:
ToddandHugo Vieira authored and GitHub committed 2022-03-31 08:48:50 -07:00
1 parent 1bb2c5983d
commit 3eb22b073a
16 files changed
+1128 -16

No files matched your search

+1
View File
@@ -72,4 +72,5 @@ const (
ConnectionsField = "connections"
CredentialTypeField = "credential_type"
CredentialMappingOverridesField = "credential_mapping_overrides"
MetricNamespace = "boundary"
)
+9 -1
View File
@@ -7,7 +7,7 @@ replace github.com/hashicorp/boundary/api => ./api
replace github.com/hashicorp/boundary/sdk => ./sdk
require (
github.com/armon/go-metrics v0.3.9
github.com/armon/go-metrics v0.3.9 // indirect
github.com/bufbuild/buf v0.56.0
github.com/fatih/color v1.13.0
github.com/fatih/structs v1.1.0
@@ -86,6 +86,8 @@ require (
require github.com/hashicorp/go-dbw v0.0.0-20211215222256-2ff0d37184ff // this is a branch and should be updated before merging
require github.com/prometheus/client_golang v1.12.1
require (
github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect
github.com/AlecAivazis/survey/v2 v2.2.9 // indirect
@@ -99,10 +101,12 @@ require (
github.com/alessio/shellescape v1.4.1 // indirect
github.com/apex/log v1.9.0 // indirect
github.com/armon/go-radix v1.0.0 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d // indirect
github.com/bgentry/speakeasy v0.1.0 // indirect
github.com/cenkalti/backoff/v3 v3.0.0 // indirect
github.com/cenkalti/backoff/v4 v4.1.0 // indirect
github.com/cespare/xxhash/v2 v2.1.2 // indirect
github.com/containerd/continuity v0.0.0-20200709052629-daa8e1ccc0bc // indirect
github.com/coreos/go-oidc/v3 v3.0.0 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.0 // indirect
@@ -153,6 +157,7 @@ require (
github.com/lib/pq v1.10.2 // indirect
github.com/mattn/go-isatty v0.0.14 // indirect
github.com/mattn/go-sqlite3 v2.0.1+incompatible // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/go-testing-interface v1.0.0 // indirect
@@ -166,6 +171,9 @@ require (
github.com/pierrec/lz4 v2.5.2+incompatible // indirect
github.com/pkg/profile v1.6.0 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/russross/blackfriday/v2 v2.0.1 // indirect
github.com/shurcooL/sanitized_anchor_name v1.0.0 // indirect
+34 -2
View File
@@ -74,6 +74,7 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
github.com/alessio/shellescape v1.4.1 h1:V7yhSDDn8LP4lc4jS8pFkt0zCnzVJlG5JXy9BVKJUX0=
github.com/alessio/shellescape v1.4.1/go.mod h1:PZAiSCk0LJaZkiCSkPv8qIobYglO3FPpyFjDCtHLS30=
github.com/alexbrainman/sspi v0.0.0-20180613141037-e580b900e9f5/go.mod h1:976q2ETgjT2snVCf2ZaBnyBbVoPERGjUz+0sofzEfro=
@@ -98,6 +99,7 @@ github.com/benbjohnson/clock v1.1.0 h1:Q92kusRqC1XV2MjkWETPvjJVqKetz1OzxZB7mHJLj
github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA=
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d h1:xDfNPAt8lFiC1UJrqV3uuy861HCTo708pDMbjHHdCas=
github.com/bgentry/go-netrc v0.0.0-20140422174119-9fd32a8b3d3d/go.mod h1:6QX/PXZ00z/TKoufEY6K/a0k6AhaJrQKdFe6OfVXsa4=
@@ -115,8 +117,11 @@ github.com/cenkalti/backoff/v4 v4.0.2/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8
github.com/cenkalti/backoff/v4 v4.1.0 h1:c8LkOFQTzuO0WBM/ae5HdGQuZPfPxp7lqBRwQRm4fSc=
github.com/cenkalti/backoff/v4 v4.1.0/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko=
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.1.2 h1:YRXhKfTDauu4ajMg1TPgFO5jnlC2HCbmLXMcTG5cbYE=
github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI=
github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI=
github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU=
@@ -583,14 +588,18 @@ github.com/jinzhu/now v1.1.3/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
github.com/jmoiron/sqlx v1.2.0/go.mod h1:1FEQNm3xlJgrMD+FBdI9+xvCksHtbpVBBw5dYhBSsks=
github.com/jpillora/backoff v0.0.0-20180909062703-3050d21c67d7/go.mod h1:2iMrUgbbvHEiQClaW2NsSzMyGHqN+rDFqY705q49KG0=
github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ=
github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM=
github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo=
github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
github.com/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/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM=
github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k=
github.com/k0kubun/pp v2.3.0+incompatible/go.mod h1:GWse8YhT0p8pT4ir3ZgBbfZild3tgzSScAn6HmfYukg=
github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0/go.mod h1:1NbS8ALrpOvjt0rHPNLyCIeMtbizbir8U//inJ+zuB8=
@@ -659,6 +668,7 @@ github.com/mattn/go-sqlite3 v1.10.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsO
github.com/mattn/go-sqlite3 v1.14.9/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU=
github.com/mattn/go-sqlite3 v2.0.1+incompatible h1:xQ15muvnzGBHpIpdrNi1DA5x0+TcBZzsIDwmw9uTHzw=
github.com/mattn/go-sqlite3 v2.0.1+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=
github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4=
github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE=
@@ -697,8 +707,9 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ
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=
github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M=
github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk=
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o=
@@ -707,6 +718,7 @@ github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs
github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns=
github.com/mutecomm/go-sqlcipher/v4 v4.4.0/go.mod h1:PyN04SaWalavxRGH9E8ZftG6Ju7rsPrGmQRjrEaVpiY=
github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U=
github.com/nakagami/firebirdsql v0.0.0-20190310045651-3c02a58cfed8/go.mod h1:86wM1zFnC6/uDBfZGNwB65O+pR2OFi5q/YQaEUid1qA=
github.com/neo4j/neo4j-go-driver v1.8.1-0.20200803113522-b626aa943eba/go.mod h1:ncO5VaFWh0Nrt+4KT4mOZboaczBZcLuHrG+/sUeP8gI=
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
@@ -762,15 +774,28 @@ github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSg
github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo=
github.com/prometheus/client_golang v1.4.0/go.mod h1:e9GMxYsXl05ICDXkRhurwBS4Q3OK1iX/F2sw+iXX5zU=
github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M=
github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0=
github.com/prometheus/client_golang v1.12.1 h1:ZiaPsmm9uiBeaSMRznKsCDNtPCS0T3JVDGF+06gjBzk=
github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY=
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo=
github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/client_model v0.2.0 h1:uq5h0d+GuxiXLJLNABMgp2qUWDPiLvgCzz2dUR+/W/M=
github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4=
github.com/prometheus/common v0.9.1/go.mod h1:yhUN8i9wzaXS3w1O07YhxHEBxD+W35wd8bs7vj7HSQ4=
github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo=
github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc=
github.com/prometheus/common v0.32.1 h1:hWIdL3N2HoUx3B8j3YN9mWor0qhY/NlEKZEaXxuIRh4=
github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls=
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/procfs v0.0.8/go.mod h1:7Qr8sr6344vo1JqZ6HhLceV9o3AJ1Ff+GxbHq6oeK9A=
github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU=
github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/prometheus/procfs v0.7.3 h1:4jVXhlkAyzOScmCkXBTOLRLTz8EeU+eyjrwB/EPq0VU=
github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA=
github.com/remyoudompheng/bigfft v0.0.0-20190728182440-6a916e37a237/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo=
github.com/rogpeppe/fastuuid v1.1.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
@@ -1028,6 +1053,7 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20210907225631-ff17edfbf26d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211015210444-4f30a5c0130f/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
@@ -1047,6 +1073,7 @@ golang.org/x/oauth2 v0.0.0-20210218202405-ba52d332ba99/go.mod h1:KelEdhl1UZF7XfJ
golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210313182246-cd4f82c27b84/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210402161424-2e8d93401602/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20210819190943-2bc19b11175f/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 h1:RerP+noqYHUQ8CMRcPlC2nvTa4dcBIjegkuWdcUDuqg=
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
@@ -1091,6 +1118,7 @@ golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191228213918-04cbcbbfeed8/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200106162015-b016eb3dc98e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200113162924-86b910548bc1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200121082415-34d275377bf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1106,6 +1134,8 @@ golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200615200032-f1bc736245b1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200826173525-f9321e4c35a6/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -1126,6 +1156,7 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w
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-20210514084401-e8d321eab015/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-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
@@ -1134,6 +1165,7 @@ golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a h1:ppl5mZgokTT8uPkmYOyEUmPTr3ypaKkg5eFOGrAmxxE=
golang.org/x/sys v0.0.0-20220204135822-1c1b9b1eba6a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
+10 -10
View File
@@ -17,7 +17,6 @@ import (
"syscall"
"time"
"github.com/armon/go-metrics"
"github.com/hashicorp/boundary/globals"
"github.com/hashicorp/boundary/internal/cmd/base/logging"
"github.com/hashicorp/boundary/internal/cmd/config"
@@ -42,6 +41,7 @@ import (
"github.com/hashicorp/go-secure-stdlib/reloadutil"
"github.com/hashicorp/go-secure-stdlib/strutil"
"github.com/mitchellh/cli"
"github.com/prometheus/client_golang/prometheus"
"google.golang.org/grpc/grpclog"
)
@@ -83,8 +83,7 @@ type Server struct {
Kms *kms.Kms
SecureRandomReader io.Reader
InmemSink *metrics.InmemSink
PrometheusEnabled bool
PrometheusRegisterer prometheus.Registerer
ReloadFuncsLock *sync.RWMutex
ReloadFuncs map[string][]reloadutil.ReloadFunc
@@ -136,13 +135,14 @@ type Server struct {
func NewServer(cmd *Command) *Server {
return &Server{
Command: cmd,
InfoKeys: make([]string, 0, 20),
Info: make(map[string]string),
SecureRandomReader: rand.Reader,
ReloadFuncsLock: new(sync.RWMutex),
ReloadFuncs: make(map[string][]reloadutil.ReloadFunc),
StderrLock: new(sync.Mutex),
Command: cmd,
InfoKeys: make([]string, 0, 20),
Info: make(map[string]string),
SecureRandomReader: rand.Reader,
ReloadFuncsLock: new(sync.RWMutex),
ReloadFuncs: make(map[string][]reloadutil.ReloadFunc),
StderrLock: new(sync.Mutex),
PrometheusRegisterer: prometheus.DefaultRegisterer,
}
}
@@ -36,6 +36,10 @@ type testServerCommandOpts struct {
// Use the well-known dev mode target method id (1234567890)
UseDevTarget bool
// Whether or not to enable metric collection. If enable metrics will use
// prometheus' default registerer.
EnableMetrics bool
}
func testServerCommand(t *testing.T, opts testServerCommandOpts) *Command {
@@ -51,6 +55,10 @@ func testServerCommand(t *testing.T, opts testServerCommandOpts) *Command {
require.NoError(cmd.SetupLogging("trace", "", "", ""))
require.NoError(cmd.SetupEventing(cmd.Logger, cmd.StderrLock, "test-server-command"))
if !opts.EnableMetrics {
cmd.PrometheusRegisterer = nil
}
if opts.CreateDevDatabase {
kmsHcl := fmt.Sprintf(rootKmsConfig, opts.ControllerKey)
parsedKmsConfig, err := config.Parse(kmsHcl)
+2
View File
@@ -19,6 +19,7 @@ import (
"github.com/hashicorp/go-secure-stdlib/listenerutil"
"github.com/mitchellh/cli"
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
// Server is a collection of all state required to serve
@@ -139,6 +140,7 @@ func createOpsHandler(lncfg *listenerutil.ListenerConfig, c *controller.Controll
mux.Handle("/health", h)
}
mux.Handle("/metrics", promhttp.Handler())
return cleanhttp.PrintablePathCheckHandler(mux, nil), nil
}
@@ -0,0 +1,227 @@
// Code generated by protoc-gen-go. DO NOT EDIT.
// versions:
// protoc-gen-go v1.27.1
// protoc v3.17.3
// source: testing/options/v1/service.proto
package protooptions
import (
_ "google.golang.org/genproto/googleapis/api/annotations"
protoreflect "google.golang.org/protobuf/reflect/protoreflect"
protoimpl "google.golang.org/protobuf/runtime/protoimpl"
reflect "reflect"
sync "sync"
)
const (
// Verify that this generated code is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(20 - protoimpl.MinVersion)
// Verify that runtime/protoimpl is sufficiently up-to-date.
_ = protoimpl.EnforceVersion(protoimpl.MaxVersion - 20)
)
// The request message.
type TestMethodRequest struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Id string `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
}
func (x *TestMethodRequest) Reset() {
*x = TestMethodRequest{}
if protoimpl.UnsafeEnabled {
mi := &file_testing_options_v1_service_proto_msgTypes[0]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *TestMethodRequest) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TestMethodRequest) ProtoMessage() {}
func (x *TestMethodRequest) ProtoReflect() protoreflect.Message {
mi := &file_testing_options_v1_service_proto_msgTypes[0]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TestMethodRequest.ProtoReflect.Descriptor instead.
func (*TestMethodRequest) Descriptor() ([]byte, []int) {
return file_testing_options_v1_service_proto_rawDescGZIP(), []int{0}
}
func (x *TestMethodRequest) GetId() string {
if x != nil {
return x.Id
}
return ""
}
// The response message.
type TestMethodResponse struct {
state protoimpl.MessageState
sizeCache protoimpl.SizeCache
unknownFields protoimpl.UnknownFields
Item string `protobuf:"bytes,1,opt,name=item,proto3" json:"item,omitempty"`
}
func (x *TestMethodResponse) Reset() {
*x = TestMethodResponse{}
if protoimpl.UnsafeEnabled {
mi := &file_testing_options_v1_service_proto_msgTypes[1]
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
ms.StoreMessageInfo(mi)
}
}
func (x *TestMethodResponse) String() string {
return protoimpl.X.MessageStringOf(x)
}
func (*TestMethodResponse) ProtoMessage() {}
func (x *TestMethodResponse) ProtoReflect() protoreflect.Message {
mi := &file_testing_options_v1_service_proto_msgTypes[1]
if protoimpl.UnsafeEnabled && x != nil {
ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x))
if ms.LoadMessageInfo() == nil {
ms.StoreMessageInfo(mi)
}
return ms
}
return mi.MessageOf(x)
}
// Deprecated: Use TestMethodResponse.ProtoReflect.Descriptor instead.
func (*TestMethodResponse) Descriptor() ([]byte, []int) {
return file_testing_options_v1_service_proto_rawDescGZIP(), []int{1}
}
func (x *TestMethodResponse) GetItem() string {
if x != nil {
return x.Item
}
return ""
}
var File_testing_options_v1_service_proto protoreflect.FileDescriptor
var file_testing_options_v1_service_proto_rawDesc = []byte{
0x0a, 0x20, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e,
0x73, 0x2f, 0x76, 0x31, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x2e, 0x70, 0x72, 0x6f,
0x74, 0x6f, 0x12, 0x12, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69,
0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x1a, 0x1c, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x61,
0x70, 0x69, 0x2f, 0x61, 0x6e, 0x6e, 0x6f, 0x74, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x70,
0x72, 0x6f, 0x74, 0x6f, 0x22, 0x23, 0x0a, 0x11, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68,
0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18,
0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x28, 0x0a, 0x12, 0x54, 0x65, 0x73,
0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12,
0x12, 0x0a, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x69,
0x74, 0x65, 0x6d, 0x32, 0x94, 0x01, 0x0a, 0x0b, 0x54, 0x65, 0x73, 0x74, 0x53, 0x65, 0x72, 0x76,
0x69, 0x63, 0x65, 0x12, 0x84, 0x01, 0x0a, 0x0a, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68,
0x6f, 0x64, 0x12, 0x25, 0x2e, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x70, 0x74,
0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68,
0x6f, 0x64, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x26, 0x2e, 0x74, 0x65, 0x73, 0x74,
0x69, 0x6e, 0x67, 0x2e, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x2e, 0x76, 0x31, 0x2e, 0x54,
0x65, 0x73, 0x74, 0x4d, 0x65, 0x74, 0x68, 0x6f, 0x64, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73,
0x65, 0x22, 0x27, 0x82, 0xd3, 0xe4, 0x93, 0x02, 0x21, 0x12, 0x0d, 0x2f, 0x76, 0x31, 0x2f, 0x74,
0x65, 0x73, 0x74, 0x2f, 0x7b, 0x69, 0x64, 0x7d, 0x5a, 0x0a, 0x12, 0x08, 0x2f, 0x76, 0x32, 0x2f,
0x74, 0x65, 0x73, 0x74, 0x62, 0x04, 0x69, 0x74, 0x65, 0x6d, 0x42, 0x4e, 0x5a, 0x4c, 0x67, 0x69,
0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x68, 0x61, 0x73, 0x68, 0x69, 0x63, 0x6f,
0x72, 0x70, 0x2f, 0x62, 0x6f, 0x75, 0x6e, 0x64, 0x61, 0x72, 0x79, 0x2f, 0x69, 0x6e, 0x74, 0x65,
0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x67, 0x65, 0x6e, 0x2f, 0x74, 0x65, 0x73, 0x74, 0x69, 0x6e, 0x67,
0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x3b, 0x70, 0x72,
0x6f, 0x74, 0x6f, 0x6f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x73, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74,
0x6f, 0x33,
}
var (
file_testing_options_v1_service_proto_rawDescOnce sync.Once
file_testing_options_v1_service_proto_rawDescData = file_testing_options_v1_service_proto_rawDesc
)
func file_testing_options_v1_service_proto_rawDescGZIP() []byte {
file_testing_options_v1_service_proto_rawDescOnce.Do(func() {
file_testing_options_v1_service_proto_rawDescData = protoimpl.X.CompressGZIP(file_testing_options_v1_service_proto_rawDescData)
})
return file_testing_options_v1_service_proto_rawDescData
}
var file_testing_options_v1_service_proto_msgTypes = make([]protoimpl.MessageInfo, 2)
var file_testing_options_v1_service_proto_goTypes = []interface{}{
(*TestMethodRequest)(nil), // 0: testing.options.v1.TestMethodRequest
(*TestMethodResponse)(nil), // 1: testing.options.v1.TestMethodResponse
}
var file_testing_options_v1_service_proto_depIdxs = []int32{
0, // 0: testing.options.v1.TestService.TestMethod:input_type -> testing.options.v1.TestMethodRequest
1, // 1: testing.options.v1.TestService.TestMethod:output_type -> testing.options.v1.TestMethodResponse
1, // [1:2] is the sub-list for method output_type
0, // [0:1] is the sub-list for method input_type
0, // [0:0] is the sub-list for extension type_name
0, // [0:0] is the sub-list for extension extendee
0, // [0:0] is the sub-list for field type_name
}
func init() { file_testing_options_v1_service_proto_init() }
func file_testing_options_v1_service_proto_init() {
if File_testing_options_v1_service_proto != nil {
return
}
if !protoimpl.UnsafeEnabled {
file_testing_options_v1_service_proto_msgTypes[0].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TestMethodRequest); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
file_testing_options_v1_service_proto_msgTypes[1].Exporter = func(v interface{}, i int) interface{} {
switch v := v.(*TestMethodResponse); i {
case 0:
return &v.state
case 1:
return &v.sizeCache
case 2:
return &v.unknownFields
default:
return nil
}
}
}
type x struct{}
out := protoimpl.TypeBuilder{
File: protoimpl.DescBuilder{
GoPackagePath: reflect.TypeOf(x{}).PkgPath(),
RawDescriptor: file_testing_options_v1_service_proto_rawDesc,
NumEnums: 0,
NumMessages: 2,
NumExtensions: 0,
NumServices: 1,
},
GoTypes: file_testing_options_v1_service_proto_goTypes,
DependencyIndexes: file_testing_options_v1_service_proto_depIdxs,
MessageInfos: file_testing_options_v1_service_proto_msgTypes,
}.Build()
File_testing_options_v1_service_proto = out.File
file_testing_options_v1_service_proto_rawDesc = nil
file_testing_options_v1_service_proto_goTypes = nil
file_testing_options_v1_service_proto_depIdxs = nil
}
@@ -0,0 +1,277 @@
// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT.
// source: testing/options/v1/service.proto
/*
Package protooptions is a reverse proxy.
It translates gRPC into RESTful JSON APIs.
*/
package protooptions
import (
"context"
"io"
"net/http"
"github.com/grpc-ecosystem/grpc-gateway/v2/runtime"
"github.com/grpc-ecosystem/grpc-gateway/v2/utilities"
"google.golang.org/grpc"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/grpclog"
"google.golang.org/grpc/metadata"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/proto"
)
// Suppress "imported and not used" errors
var _ codes.Code
var _ io.Reader
var _ status.Status
var _ = runtime.String
var _ = utilities.NewDoubleArray
var _ = metadata.Join
func request_TestService_TestMethod_0(ctx context.Context, marshaler runtime.Marshaler, client TestServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq TestMethodRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
}
protoReq.Id, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
}
msg, err := client.TestMethod(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_TestService_TestMethod_0(ctx context.Context, marshaler runtime.Marshaler, server TestServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq TestMethodRequest
var metadata runtime.ServerMetadata
var (
val string
ok bool
err error
_ = err
)
val, ok = pathParams["id"]
if !ok {
return nil, metadata, status.Errorf(codes.InvalidArgument, "missing parameter %s", "id")
}
protoReq.Id, err = runtime.String(val)
if err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "type mismatch, parameter: %s, error: %v", "id", err)
}
msg, err := server.TestMethod(ctx, &protoReq)
return msg, metadata, err
}
var (
filter_TestService_TestMethod_1 = &utilities.DoubleArray{Encoding: map[string]int{}, Base: []int(nil), Check: []int(nil)}
)
func request_TestService_TestMethod_1(ctx context.Context, marshaler runtime.Marshaler, client TestServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq TestMethodRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_TestService_TestMethod_1); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := client.TestMethod(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD))
return msg, metadata, err
}
func local_request_TestService_TestMethod_1(ctx context.Context, marshaler runtime.Marshaler, server TestServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) {
var protoReq TestMethodRequest
var metadata runtime.ServerMetadata
if err := req.ParseForm(); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
if err := runtime.PopulateQueryParameters(&protoReq, req.Form, filter_TestService_TestMethod_1); err != nil {
return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err)
}
msg, err := server.TestMethod(ctx, &protoReq)
return msg, metadata, err
}
// RegisterTestServiceHandlerServer registers the http handlers for service TestService to "mux".
// UnaryRPC :call TestServiceServer directly.
// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906.
// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterTestServiceHandlerFromEndpoint instead.
func RegisterTestServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server TestServiceServer) error {
mux.Handle("GET", pattern_TestService_TestMethod_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/testing.options.v1.TestService/TestMethod", runtime.WithHTTPPathPattern("/v1/test/{id}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_TestService_TestMethod_0(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_TestService_TestMethod_0(ctx, mux, outboundMarshaler, w, req, response_TestService_TestMethod_0{resp}, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_TestService_TestMethod_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
var stream runtime.ServerTransportStream
ctx = grpc.NewContextWithServerTransportStream(ctx, &stream)
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req, "/testing.options.v1.TestService/TestMethod", runtime.WithHTTPPathPattern("/v2/test"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := local_request_TestService_TestMethod_1(rctx, inboundMarshaler, server, req, pathParams)
md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer())
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_TestService_TestMethod_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
// RegisterTestServiceHandlerFromEndpoint is same as RegisterTestServiceHandler but
// automatically dials to "endpoint" and closes the connection when "ctx" gets done.
func RegisterTestServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) {
conn, err := grpc.Dial(endpoint, opts...)
if err != nil {
return err
}
defer func() {
if err != nil {
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
return
}
go func() {
<-ctx.Done()
if cerr := conn.Close(); cerr != nil {
grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr)
}
}()
}()
return RegisterTestServiceHandler(ctx, mux, conn)
}
// RegisterTestServiceHandler registers the http handlers for service TestService to "mux".
// The handlers forward requests to the grpc endpoint over "conn".
func RegisterTestServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error {
return RegisterTestServiceHandlerClient(ctx, mux, NewTestServiceClient(conn))
}
// RegisterTestServiceHandlerClient registers the http handlers for service TestService
// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "TestServiceClient".
// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "TestServiceClient"
// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in
// "TestServiceClient" to call the correct interceptors.
func RegisterTestServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client TestServiceClient) error {
mux.Handle("GET", pattern_TestService_TestMethod_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/testing.options.v1.TestService/TestMethod", runtime.WithHTTPPathPattern("/v1/test/{id}"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_TestService_TestMethod_0(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_TestService_TestMethod_0(ctx, mux, outboundMarshaler, w, req, response_TestService_TestMethod_0{resp}, mux.GetForwardResponseOptions()...)
})
mux.Handle("GET", pattern_TestService_TestMethod_1, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) {
ctx, cancel := context.WithCancel(req.Context())
defer cancel()
inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req)
rctx, err := runtime.AnnotateContext(ctx, mux, req, "/testing.options.v1.TestService/TestMethod", runtime.WithHTTPPathPattern("/v2/test"))
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
resp, md, err := request_TestService_TestMethod_1(rctx, inboundMarshaler, client, req, pathParams)
ctx = runtime.NewServerMetadataContext(ctx, md)
if err != nil {
runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err)
return
}
forward_TestService_TestMethod_1(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...)
})
return nil
}
type response_TestService_TestMethod_0 struct {
proto.Message
}
func (m response_TestService_TestMethod_0) XXX_ResponseBody() interface{} {
response := m.Message.(*TestMethodResponse)
return response.Item
}
var (
pattern_TestService_TestMethod_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 1, 0, 4, 1, 5, 2}, []string{"v1", "test", "id"}, ""))
pattern_TestService_TestMethod_1 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1}, []string{"v2", "test"}, ""))
)
var (
forward_TestService_TestMethod_0 = runtime.ForwardResponseMessage
forward_TestService_TestMethod_1 = runtime.ForwardResponseMessage
)
@@ -0,0 +1,101 @@
// Code generated by protoc-gen-go-grpc. DO NOT EDIT.
package protooptions
import (
context "context"
grpc "google.golang.org/grpc"
codes "google.golang.org/grpc/codes"
status "google.golang.org/grpc/status"
)
// This is a compile-time assertion to ensure that this generated file
// is compatible with the grpc package it is being compiled against.
// Requires gRPC-Go v1.32.0 or later.
const _ = grpc.SupportPackageIsVersion7
// TestServiceClient is the client API for TestService service.
//
// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://pkg.go.dev/google.golang.org/grpc/?tab=doc#ClientConn.NewStream.
type TestServiceClient interface {
TestMethod(ctx context.Context, in *TestMethodRequest, opts ...grpc.CallOption) (*TestMethodResponse, error)
}
type testServiceClient struct {
cc grpc.ClientConnInterface
}
func NewTestServiceClient(cc grpc.ClientConnInterface) TestServiceClient {
return &testServiceClient{cc}
}
func (c *testServiceClient) TestMethod(ctx context.Context, in *TestMethodRequest, opts ...grpc.CallOption) (*TestMethodResponse, error) {
out := new(TestMethodResponse)
err := c.cc.Invoke(ctx, "/testing.options.v1.TestService/TestMethod", in, out, opts...)
if err != nil {
return nil, err
}
return out, nil
}
// TestServiceServer is the server API for TestService service.
// All implementations must embed UnimplementedTestServiceServer
// for forward compatibility
type TestServiceServer interface {
TestMethod(context.Context, *TestMethodRequest) (*TestMethodResponse, error)
mustEmbedUnimplementedTestServiceServer()
}
// UnimplementedTestServiceServer must be embedded to have forward compatible implementations.
type UnimplementedTestServiceServer struct {
}
func (UnimplementedTestServiceServer) TestMethod(context.Context, *TestMethodRequest) (*TestMethodResponse, error) {
return nil, status.Errorf(codes.Unimplemented, "method TestMethod not implemented")
}
func (UnimplementedTestServiceServer) mustEmbedUnimplementedTestServiceServer() {}
// UnsafeTestServiceServer may be embedded to opt out of forward compatibility for this service.
// Use of this interface is not recommended, as added methods to TestServiceServer will
// result in compilation errors.
type UnsafeTestServiceServer interface {
mustEmbedUnimplementedTestServiceServer()
}
func RegisterTestServiceServer(s grpc.ServiceRegistrar, srv TestServiceServer) {
s.RegisterService(&TestService_ServiceDesc, srv)
}
func _TestService_TestMethod_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) {
in := new(TestMethodRequest)
if err := dec(in); err != nil {
return nil, err
}
if interceptor == nil {
return srv.(TestServiceServer).TestMethod(ctx, in)
}
info := &grpc.UnaryServerInfo{
Server: srv,
FullMethod: "/testing.options.v1.TestService/TestMethod",
}
handler := func(ctx context.Context, req interface{}) (interface{}, error) {
return srv.(TestServiceServer).TestMethod(ctx, req.(*TestMethodRequest))
}
return interceptor(ctx, in, info, handler)
}
// TestService_ServiceDesc is the grpc.ServiceDesc for TestService service.
// It's only intended for direct use with grpc.RegisterService,
// and not to be introspected or modified (even as a copy)
var TestService_ServiceDesc = grpc.ServiceDesc{
ServiceName: "testing.options.v1.TestService",
HandlerType: (*TestServiceServer)(nil),
Methods: []grpc.MethodDesc{
{
MethodName: "TestMethod",
Handler: _TestService_TestMethod_Handler,
},
},
Streams: []grpc.StreamDesc{},
Metadata: "testing/options/v1/service.proto",
}
@@ -0,0 +1,31 @@
syntax = "proto3";
package testing.options.v1;
option go_package = "github.com/hashicorp/boundary/internal/gen/testing/protooptions;protooptions";
import "google/api/annotations.proto";
// The test service definition. This is just a service that can be used to
// test options applied to services.
service TestService {
rpc TestMethod(TestMethodRequest) returns (TestMethodResponse) {
option (google.api.http) = {
get: "/v1/test/{id}"
response_body: "item"
additional_bindings {
get: "/v2/test"
}
};
}
}
// The request message.
message TestMethodRequest {
string id = 1;
}
// The response message.
message TestMethodResponse {
string item = 1;
}
@@ -26,6 +26,7 @@ import (
"github.com/hashicorp/boundary/internal/servers"
"github.com/hashicorp/boundary/internal/servers/controller/common"
"github.com/hashicorp/boundary/internal/servers/controller/handlers/health"
"github.com/hashicorp/boundary/internal/servers/controller/internal/metric"
"github.com/hashicorp/boundary/internal/session"
"github.com/hashicorp/boundary/internal/target"
"github.com/hashicorp/boundary/internal/types/scope"
@@ -88,6 +89,7 @@ type Controller struct {
}
func New(ctx context.Context, conf *Config) (*Controller, error) {
metric.InitializeApiCollectors(conf.PrometheusRegisterer)
c := &Controller{
conf: conf,
logger: conf.Logger.Named("controller"),
+6 -1
View File
@@ -38,6 +38,7 @@ import (
"github.com/hashicorp/boundary/internal/servers/controller/handlers/sessions"
"github.com/hashicorp/boundary/internal/servers/controller/handlers/targets"
"github.com/hashicorp/boundary/internal/servers/controller/handlers/users"
"github.com/hashicorp/boundary/internal/servers/controller/internal/metric"
"github.com/hashicorp/go-cleanhttp"
"github.com/hashicorp/go-secure-stdlib/listenerutil"
"github.com/hashicorp/go-secure-stdlib/strutil"
@@ -72,8 +73,12 @@ func (c *Controller) apiHandler(props HandlerProperties) (http.Handler, error) {
callbackInterceptingHandler := wrapHandlerWithCallbackInterceptor(commonWrappedHandler, c)
printablePathCheckHandler := cleanhttp.PrintablePathCheckHandler(callbackInterceptingHandler, nil)
eventsHandler, err := common.WrapWithEventsHandler(printablePathCheckHandler, c.conf.Eventer, c.kms, props.ListenerConfig)
if err != nil {
return nil, err
}
metricsHandler := metric.InstrumentApiHandler(eventsHandler)
return eventsHandler, err
return metricsHandler, nil
}
// GetHealthHandler returns a gRPC Gateway mux that is registered against the
@@ -0,0 +1,271 @@
// Package metric provides functions to initialize the controller specific
// collectors and hooks to measure metrics and update the relevant collectors.
package metric
import (
"fmt"
"net/http"
"path"
"regexp"
"strconv"
"strings"
"github.com/hashicorp/boundary/globals"
"github.com/hashicorp/boundary/internal/gen/controller/api/services"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
grpcpb "google.golang.org/genproto/googleapis/api/annotations"
"google.golang.org/protobuf/proto"
"google.golang.org/protobuf/reflect/protoreflect"
"google.golang.org/protobuf/reflect/protoregistry"
"google.golang.org/protobuf/types/descriptorpb"
)
var (
pathRegex map[*regexp.Regexp]string
expectedPathsToMethods map[string][]string
)
func init() {
expectedPathsToMethods = apiPathsAndMethods()
pathRegex = make(map[*regexp.Regexp]string)
for p := range expectedPathsToMethods {
pathRegex[buildRegexFromPath(p)] = p
}
}
// gatherPathInfo populates the provided map with the paths associated with
// the provided HttpRule proto option as well as the path information contained
// in any embedded AdditionalBindings in that HttpRule.
func gatherPathInfo(rule *grpcpb.HttpRule, paths map[string][]string) {
switch r := rule.GetPattern().(type) {
case *grpcpb.HttpRule_Get:
paths[r.Get] = append(paths[r.Get], http.MethodGet)
case *grpcpb.HttpRule_Post:
paths[r.Post] = append(paths[r.Post], http.MethodPost)
case *grpcpb.HttpRule_Patch:
paths[r.Patch] = append(paths[r.Patch], http.MethodPatch)
case *grpcpb.HttpRule_Put:
paths[r.Put] = append(paths[r.Put], http.MethodPut)
case *grpcpb.HttpRule_Delete:
paths[r.Delete] = append(paths[r.Delete], http.MethodDelete)
default:
panic("unknown rule of ")
}
for _, additional := range rule.AdditionalBindings {
gatherPathInfo(additional, paths)
}
}
func gatherServicePathsAndMethods(fd protoreflect.FileDescriptor, paths map[string][]string) error {
for j := 0; j < fd.Services().Len(); j++ {
sd := fd.Services().Get(j)
for i := 0; i < sd.Methods().Len(); i++ {
r := sd.Methods().Get(i)
opts := r.Options().(*descriptorpb.MethodOptions)
httpRule := proto.GetExtension(opts, grpcpb.E_Http).(*grpcpb.HttpRule)
if proto.Equal(httpRule, &grpcpb.HttpRule{}) || httpRule == nil {
return fmt.Errorf("empty or no http rule found on service method %q", r.FullName())
}
gatherPathInfo(httpRule, paths)
}
}
return nil
}
// apiPathsAndMethods provides the pathing information for all services
// registered to the controller API. This does not include any paths that are
// defined outside of the protobufs such as anything using the OPTION method
// or any other paths registered like the dev UI passthrough path.
func apiPathsAndMethods() map[string][]string {
paths := make(map[string][]string)
protoregistry.GlobalFiles.RangeFilesByPackage(
services.File_controller_api_services_v1_user_service_proto.Package(),
func(f protoreflect.FileDescriptor) bool {
if err := gatherServicePathsAndMethods(f, paths); err != nil {
panic(err)
}
return true
})
return paths
}
func buildRegexFromPath(p string) *regexp.Regexp {
// a public id in boundary consists of a some prefix, an underscore and
// at least 10 alphanumerical characters like "h_1234567890".
const idRegexp = "[[:alnum:]]{1,}_[[:alnum:]]{10,}"
// Replace any tag in the form of {id} or {auth_method_id} with the above
// regex so we can match paths to that when measuring requests.
pWithId := string(regexp.MustCompile("\\{[^\\}]*id\\}").ReplaceAll([]byte(p), []byte(idRegexp)))
// Escape everything except for our id regexp.
var seg []string
for _, s := range strings.Split(pWithId, idRegexp) {
seg = append(seg, regexp.QuoteMeta(s))
}
escapedPathRegex := strings.Join(seg, idRegexp)
return regexp.MustCompile(fmt.Sprintf("^%s$", escapedPathRegex))
}
const (
invalidPathValue = "invalid"
labelHttpCode = "code"
labelHttpPath = "path"
labelHttpMethod = "method"
apiSubSystem = "controller_api"
)
var (
// 100 bytes, 1kb, 10kb, 100kb, 1mb, 10mb, 100mb, 1gb
msgSizeBuckets = prometheus.ExponentialBuckets(100, 10, 8)
// httpRequestLatency collects measurements of how long it takes
// the boundary system to reply to a request to the controller api
// from the time that boundary received the request.
httpRequestLatency prometheus.ObserverVec = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: globals.MetricNamespace,
Subsystem: apiSubSystem,
Name: "http_request_duration_seconds",
Help: "Histogram of latencies for HTTP requests.",
Buckets: prometheus.DefBuckets,
},
[]string{labelHttpCode, labelHttpPath, labelHttpMethod},
)
// httpRequestSize collections measurements of how large each request
// to the boundary controller api is.
httpRequestSize prometheus.ObserverVec = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: globals.MetricNamespace,
Subsystem: apiSubSystem,
Name: "http_request_size_bytes",
Help: "Histogram of request sizes for HTTP requests.",
Buckets: msgSizeBuckets,
},
[]string{labelHttpCode, labelHttpPath, labelHttpMethod},
)
// httpRequestSize collections measurements of how large each response
// from the boundary controller api is.
httpResponseSize prometheus.ObserverVec = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: globals.MetricNamespace,
Subsystem: apiSubSystem,
Name: "http_response_size_bytes",
Help: "Histogram of response sizes for HTTP responses.",
Buckets: msgSizeBuckets,
},
[]string{labelHttpCode, labelHttpPath, labelHttpMethod},
)
)
var universalStatusCodes = []int{
http.StatusUnauthorized,
http.StatusForbidden,
http.StatusNotFound,
http.StatusMethodNotAllowed,
http.StatusBadRequest,
http.StatusInternalServerError,
http.StatusGatewayTimeout,
}
// Codes which are only currently used in the authentication flow
var authenticationStatusCodes = []int{
http.StatusAccepted,
http.StatusFound,
}
var expectedStatusCodesPerMethod = map[string][]int{
http.MethodGet: append(universalStatusCodes,
http.StatusOK),
http.MethodPost: append(universalStatusCodes,
append(authenticationStatusCodes, http.StatusOK)...),
http.MethodPatch: append(universalStatusCodes,
http.StatusOK),
// delete methods always returns no content instead of a StatusOK
http.MethodDelete: append(universalStatusCodes,
http.StatusNoContent),
http.MethodOptions: {
http.StatusNoContent,
http.StatusForbidden,
http.StatusMethodNotAllowed,
},
}
// pathLabel maps the requested path the the label value recorded for metrics
func pathLabel(incomingPath string) string {
if incomingPath == "" || incomingPath[0] != '/' {
incomingPath = fmt.Sprintf("/%s", incomingPath)
}
incomingPath = path.Clean(incomingPath)
for r, ep := range pathRegex {
if r.Match([]byte(incomingPath)) {
return ep
}
}
return invalidPathValue
}
// InstrumentApiHandler provides a handler which measures api
// 1. The response size
// 2. The request size
// 3. The request latency
// and attaches status code, method, and path labels for each of these
// measurements.
func InstrumentApiHandler(wrapped http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
l := prometheus.Labels{
labelHttpPath: pathLabel(req.URL.Path),
}
promhttp.InstrumentHandlerDuration(
httpRequestLatency.MustCurryWith(l),
promhttp.InstrumentHandlerRequestSize(
httpResponseSize.MustCurryWith(l),
promhttp.InstrumentHandlerResponseSize(
httpResponseSize.MustCurryWith(l),
wrapped,
),
),
).ServeHTTP(rw, req)
})
}
// InitializeApiCollectors registers the api collectors to the default
// prometheus register and initializes them to 0 for all possible label
// combinations.
func InitializeApiCollectors(r prometheus.Registerer) {
if r == nil {
return
}
r.MustRegister(httpResponseSize, httpRequestSize, httpRequestLatency)
for p, methods := range expectedPathsToMethods {
for _, m := range methods {
for _, sc := range expectedStatusCodesPerMethod[m] {
l := prometheus.Labels{labelHttpCode: strconv.Itoa(sc), labelHttpPath: p, labelHttpMethod: strings.ToLower(m)}
httpResponseSize.With(l)
httpRequestSize.With(l)
httpRequestLatency.With(l)
}
}
}
// When an invalid path is found, any method is possible both we expect
// an error response.
p := invalidPathValue
for m := range expectedStatusCodesPerMethod {
for _, sc := range []int{http.StatusNotFound, http.StatusMethodNotAllowed} {
l := prometheus.Labels{labelHttpCode: strconv.Itoa(sc), labelHttpPath: p, labelHttpMethod: strings.ToLower(m)}
httpResponseSize.With(l)
httpRequestSize.With(l)
httpRequestLatency.With(l)
}
}
}
@@ -0,0 +1,135 @@
package metric
import (
"net/http"
"testing"
"github.com/hashicorp/boundary/internal/gen/testing/protooptions"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestBuildRegexFromPath(t *testing.T) {
cases := []struct {
path string
match []string
dont []string
}{
{
path: "/v1/pathsomething/{id}:test-thing",
match: []string{
"/v1/pathsomething/a4s_aKsdFh723018djsa:test-thing",
"/v1/pathsomething/h_1234567890:test-thing",
},
dont: []string{
"/v1/pathsomething/{id}:test-thing",
"/v1/pathsomething/{any_old_id}:test-thing",
"/v1/pathsomething:test-thing",
"/v1/pathsomething/not-an-id:test-thing",
"/v1/pathsomething/a4s_aKsdFh723018djsa:other-thing",
},
},
{
path: "/v1/pathsomething/{auth_method_id}:authenticate",
match: []string{
"/v1/pathsomething/a4s_aKsdFh723018djsa:authenticate",
"/v1/pathsomething/am_1234567890:authenticate",
},
dont: []string{
"/v1/pathsomething/{id}:authenticate",
"/v1/pathsomething/{auth_method}:authenticate",
},
},
{
path: "/v1/pathsomething/{non_id_tag}:test",
match: []string{
"/v1/pathsomething/{non_id_tag}:test",
},
dont: []string{
"/v1/pathsomething/h_1234567890:test",
"/v1/pathsomething/.*:test",
},
},
{
path: "/v1/pathsomething/a?",
match: []string{
"/v1/pathsomething/a?",
},
dont: []string{
"/v1/pathsomething/",
"/v1/pathsomething/a",
"/v1/pathsomething/aa",
},
},
}
for _, tc := range cases {
t.Run(tc.path, func(t *testing.T) {
r := buildRegexFromPath(tc.path)
for _, m := range tc.match {
assert.True(t, r.Match([]byte(m)))
}
for _, d := range tc.dont {
assert.False(t, r.Match([]byte(d)))
}
})
}
}
func TestPathLabel(t *testing.T) {
cases := []struct {
in string
want string
}{
{
in: "/v1/accounts",
want: "/v1/accounts",
},
{
in: "v1/accounts",
want: "/v1/accounts",
},
{
in: "/v1/hosts",
want: "/v1/hosts",
},
{
in: "/v2/accounts",
want: "invalid",
},
{
in: "/v1/accounts/a_1234567890",
want: "/v1/accounts/{id}",
},
{
in: "v1/accounts/a_1234567890",
want: "/v1/accounts/{id}",
},
{
in: "/v1/accounts/a_1234567890:set-password",
want: "/v1/accounts/{id}:set-password",
},
{
in: "v1/accounts/a_1234567890:set-password",
want: "/v1/accounts/{id}:set-password",
},
{
// mistype the custom action
in: "/v1/accounts/a_1234567890:set-passwords",
want: "invalid",
},
}
for _, tc := range cases {
t.Run(tc.in, func(t *testing.T) {
assert.Equal(t, tc.want, pathLabel(tc.in))
})
}
}
func TestServicePathsAndMethods(t *testing.T) {
paths := make(map[string][]string)
require.NoError(t, gatherServicePathsAndMethods(protooptions.File_testing_options_v1_service_proto, paths))
assert.Equal(t, map[string][]string{
"/v1/test/{id}": {http.MethodGet},
"/v2/test": {http.MethodGet},
}, paths)
}
+7 -2
View File
@@ -10,8 +10,6 @@ import (
"testing"
"time"
"github.com/hashicorp/boundary/internal/session"
grpc_middleware "github.com/grpc-ecosystem/go-grpc-middleware"
"github.com/hashicorp/boundary/api"
"github.com/hashicorp/boundary/api/authmethods"
@@ -27,10 +25,12 @@ import (
"github.com/hashicorp/boundary/internal/kms"
"github.com/hashicorp/boundary/internal/observability/event"
"github.com/hashicorp/boundary/internal/servers"
"github.com/hashicorp/boundary/internal/session"
"github.com/hashicorp/go-hclog"
wrapping "github.com/hashicorp/go-kms-wrapping/v2"
"github.com/hashicorp/go-secure-stdlib/base62"
"github.com/hashicorp/go-secure-stdlib/strutil"
"github.com/prometheus/client_golang/prometheus"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"google.golang.org/grpc/test/bufconn"
@@ -393,6 +393,10 @@ type TestControllerOpts struct {
// The logger to use, or one will be created
Logger hclog.Logger
// The registerer to use for registering all the collectors. Nil means
// no metrics are registered.
PrometheusRegisterer prometheus.Registerer
// A cluster address for overriding the advertised controller listener
// (overrides address provided in config, if any)
PublicClusterAddr string
@@ -519,6 +523,7 @@ func TestControllerConfig(t *testing.T, ctx context.Context, tc *TestController,
})
}
tc.b.PrometheusRegisterer = opts.PrometheusRegisterer
if opts.Config.Controller == nil {
opts.Config.Controller = new(config.Controller)
}
@@ -10,4 +10,11 @@ func Test_TestController(t *testing.T) {
tc := NewTestController(t, nil)
defer tc.Shutdown()
})
t.Run("start 2 controllers", func(t *testing.T) {
t.Parallel()
tc1 := NewTestController(t, nil)
tc2 := NewTestController(t, nil)
defer tc1.Shutdown()
defer tc2.Shutdown()
})
}