Compare commits

..
9 changed files with 283 additions and 223 deletions

No files matched your search

+7 -7
View File
@@ -1,6 +1,6 @@
module github.com/hashicorp/boundary-plugin-minio
go 1.22.2
go 1.21.5
require (
github.com/google/go-cmp v0.6.0
@@ -11,7 +11,7 @@ require (
github.com/ory/dockertest/v3 v3.10.0
github.com/stretchr/testify v1.8.4
google.golang.org/grpc v1.59.0
google.golang.org/protobuf v1.33.0
google.golang.org/protobuf v1.32.0
)
require (
@@ -22,7 +22,7 @@ require (
github.com/containerd/continuity v0.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/docker/cli v20.10.17+incompatible // indirect
github.com/docker/docker v24.0.9+incompatible // indirect
github.com/docker/docker v20.10.7+incompatible // indirect
github.com/docker/go-connections v0.4.0 // indirect
github.com/docker/go-units v0.4.0 // indirect
github.com/dustin/go-humanize v1.0.1 // indirect
@@ -54,7 +54,7 @@ require (
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/opencontainers/go-digest v1.0.0 // indirect
github.com/opencontainers/image-spec v1.0.2 // indirect
github.com/opencontainers/runc v1.1.12 // indirect
github.com/opencontainers/runc v1.1.5 // indirect
github.com/philhofer/fwd v1.1.2 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
@@ -76,11 +76,11 @@ require (
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
github.com/xeipuuv/gojsonschema v1.2.0 // indirect
github.com/yusufpapurcu/wmi v1.2.3 // indirect
golang.org/x/crypto v0.22.0 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/mod v0.9.0 // indirect
golang.org/x/net v0.24.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sync v0.3.0 // indirect
golang.org/x/sys v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.7.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20231016165738-49dd2c1f3d0b // indirect
+44 -12
View File
@@ -1,5 +1,6 @@
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
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.2.0 h1:3MEsd0SM6jqZojhjLWWeBY+Kcjy9i6MQAeY7YgDP83g=
@@ -16,18 +17,24 @@ github.com/bgentry/speakeasy v0.1.0 h1:ByYyxL9InA1OWqxJqqp2A5pYHUrCiAL6K3J+LKSsQ
github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
github.com/cenkalti/backoff/v4 v4.1.3 h1:cFAlzYUlVYDysBEH2T5hyJZMh3+5+WCBvSnK6Q8UtC4=
github.com/cenkalti/backoff/v4 v4.1.3/go.mod h1:scbssz8iZGpm3xbr14ovlUdkxfGXNInqkPWOWmG2CLw=
github.com/checkpoint-restore/go-criu/v5 v5.3.0/go.mod h1:E/eQpaFtUKGOOSEBZgmKAcn+zUUwWxqcaKZlF54wK8E=
github.com/cilium/ebpf v0.7.0/go.mod h1:/oI2+1shJiTGAMgl6/RgJr36Eo1jzrRcAWbcXO2usCA=
github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U=
github.com/containerd/continuity v0.3.0 h1:nisirsYROK15TAMVukJOUyGJjz4BNQJBVsNvAXZJ/eg=
github.com/containerd/continuity v0.3.0/go.mod h1:wJEAIwKOm/pBZuBd0JmeTvnLquTB1Ag8espWhkykbPM=
github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/creack/pty v1.1.11 h1:07n33Z8lZxZ2qwegKbObQohDhXDQxiMMz1NOUGYlesw=
github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/cyphar/filepath-securejoin v0.2.3/go.mod h1:aPGpWjXOXUn2NCNjFvBE6aRxGGx79pTxQpKOJNYHHl4=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/docker/cli v20.10.17+incompatible h1:eO2KS7ZFeov5UJeaDmIs1NFEDRf32PaqRpvoEkKBy5M=
github.com/docker/cli v20.10.17+incompatible/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
github.com/docker/docker v24.0.9+incompatible h1:HPGzNmwfLZWdxHqK9/II92pyi1EpYKsAqcl4G0Of9v0=
github.com/docker/docker v24.0.9+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
github.com/docker/docker v20.10.7+incompatible h1:Z6O9Nhsjv+ayUEeI1IojKbYcsGdgYSNqxe1s2MYzUhQ=
github.com/docker/docker v20.10.7+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
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.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
@@ -36,12 +43,15 @@ github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkp
github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto=
github.com/fatih/color v1.15.0 h1:kOqh6YHBtK8aywxGerMG2Eq3H6Qgoqeo13Bk2Mv/nBs=
github.com/fatih/color v1.15.0/go.mod h1:0h5ZqXfHYED7Bhv2ZJamyIOUej9KtShiJESRwBDUSsw=
github.com/frankban/quicktest v1.11.3/go.mod h1:wRf/ReqHper53s+kmmSZizM8NamnL3IM0I9ntUbOk+k=
github.com/go-ole/go-ole v1.2.6 h1:/Fpf6oFPoeFik9ty7siob0G6Ke8QvQEuVcuChpwXzpY=
github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
github.com/go-sql-driver/mysql v1.6.0 h1:BCTh4TKNUYmOmMUcQ3IipzF5prigylS7XXjEkfCHuOE=
github.com/go-sql-driver/mysql v1.6.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/go-test/deep v1.0.4 h1:u2CU3YKy9I2pmu9pX0eq50wCgjfGIt539SqR7FbHiho=
github.com/go-test/deep v1.0.4/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
github.com/godbus/dbus/v5 v5.0.6/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
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.5.0 h1:7cYmW1XlMY7h7ii7UhUyChSgS5wUJEnm9uZVTGqOWzg=
@@ -126,6 +136,7 @@ github.com/klauspost/cpuid/v2 v2.2.6 h1:ndNyv040zDGIDh8thGkXYjnFtiN02M1PVVF+JE/4
github.com/klauspost/cpuid/v2 v2.2.6/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws=
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.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=
@@ -164,6 +175,7 @@ github.com/mitchellh/pointerstructure v1.2.1 h1:ZhBBeX8tSlRpu/FFhXH4RC4OJzFlqsQh
github.com/mitchellh/pointerstructure v1.2.1/go.mod h1:BRAsLI5zgXmw97Lf6s25bs8ohIXc3tViBH44KcwB2g4=
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
github.com/moby/sys/mountinfo v0.5.0/go.mod h1:3bMD3Rg+zkqx8MRYPi7Pyb0Ie97QEBmdxbhnCLlSvSU=
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635 h1:rzf0wL0CHVc8CEsgyygG0Mn9CNCCPZqOPaz8RiiHYQk=
github.com/moby/term v0.0.0-20201216013528-df9cb8a40635/go.mod h1:FBS0z0QWA44HXygs7VXDUOGoN/1TV3RuWkLO04am3wc=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -171,14 +183,17 @@ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
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/mrunalp/fileutils v0.5.0/go.mod h1:M1WthSahJixYnrXQl/DFQuteStB1weuxD2QJNHXfbSQ=
github.com/oklog/run v1.1.0 h1:GEenZ1cK0+q0+wsJew9qUg/DyD8k3JzYsZAi5gYi2mA=
github.com/oklog/run v1.1.0/go.mod h1:sVPdnTZT1zYwAJeCMu2Th4T21pA3FPOQRfWjQlk7DVU=
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.0.2 h1:9yCKha/T5XdGtO0q9Q9a6T5NUCsTn/DrBg0D7ufOcFM=
github.com/opencontainers/image-spec v1.0.2/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
github.com/opencontainers/runc v1.1.12 h1:BOIssBaW1La0/qbNZHXOOa71dZfZEQOzW7dqQf3phss=
github.com/opencontainers/runc v1.1.12/go.mod h1:S+lQwSfncpBha7XTy/5lBwWgm5+y5Ma/O44Ekby9FK8=
github.com/opencontainers/runc v1.1.5 h1:L44KXEpKmfWDcS02aeGm8QNTFXTo2D+8MYGDIJ/GDEs=
github.com/opencontainers/runc v1.1.5/go.mod h1:1J5XiS+vdZ3wCyZybsuxXZWGrgSr8fFJHLXuG2PsnNg=
github.com/opencontainers/runtime-spec v1.0.3-0.20210326190908-1c3f411f0417/go.mod h1:jwyrGlmzljRJv/Fgzds9SsS/C5hL+LL3ko9hs6T5lQ0=
github.com/opencontainers/selinux v1.10.0/go.mod h1:2i0OySw99QjzBBQByd1Gr9gSjvuho1lHsJxIJ3gGbJI=
github.com/ory/dockertest/v3 v3.10.0 h1:4K3z2VMe8Woe++invjaTB7VRyQXQy5UY+loujO4aNE4=
github.com/ory/dockertest/v3 v3.10.0/go.mod h1:nr57ZbRWMqfsdGdFNLHz5jjNdDb7VVFnzAeW1n5N1Lg=
github.com/philhofer/fwd v1.1.2 h1:bnDivRJ1EWPjUIRXV5KfORO897HTbpFAQddBdE8t7Gw=
@@ -207,10 +222,12 @@ github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjR
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/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk=
github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc=
github.com/safchain/ethtool v0.3.0 h1:gimQJpsI6sc1yIqP/y8GYgiXn/NjgvpM0RNoWLVVmP0=
github.com/safchain/ethtool v0.3.0/go.mod h1:SA9BwrgyAqNo7M+uaL6IYbxpm5wk3L7Mm6ocLW+CJUs=
github.com/seccomp/libseccomp-golang v0.9.2-0.20220502022130-f33da4d89646/go.mod h1:JA8cRccbGaA1s33RQf7Y1+q9gHmZX1yB/z9WDN1C6fg=
github.com/secure-io/sio-go v0.3.1 h1:dNvY9awjabXTYGsTF1PiCySl9Ltofk9GA3VdWlo7rRc=
github.com/secure-io/sio-go v0.3.1/go.mod h1:+xbkjDzPjwh4Axd07pRKSNriS9SCiYksWnZqdnfpQxs=
github.com/shirou/gopsutil/v3 v3.23.12 h1:z90NtUkp3bMtmICZKpC4+WaknU1eXtp5vtbQ11DgpE4=
@@ -221,6 +238,8 @@ github.com/shoenig/test v0.6.4 h1:kVTaSd7WLz5WZ2IaoM0RSzRsUD+m8wRR+5qvntpn4LU=
github.com/shoenig/test v0.6.4/go.mod h1:byHiCGXqrVaflBLAMq/srcZIHynQPQgeyvkvXnjqq0k=
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.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
github.com/spf13/cast v1.5.0 h1:rj3WzYc11XZaIZMPKmwP96zkFEnnAmV8s6XbB2aY32w=
@@ -229,6 +248,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw=
github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo=
github.com/stretchr/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.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
@@ -236,12 +256,16 @@ 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.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/syndtr/gocapability v0.0.0-20200815063812-42c35b437635/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww=
github.com/tinylib/msgp v1.1.8 h1:FCXC1xanKO4I8plpHGH2P7koL/RzZs12l/+r7vakfm0=
github.com/tinylib/msgp v1.1.8/go.mod h1:qkpG+2ldGg4xRFmx+jfTvZPxfGFhi64BcnL9vkCm/Tw=
github.com/tklauser/go-sysconf v0.3.12 h1:0QaGUFOdQaIVdPgfITYzaTegZvdCjmYO52cSFAEVmqU=
github.com/tklauser/go-sysconf v0.3.12/go.mod h1:Ho14jnntGE1fpdOqQEEaiKRpvIavV0hSfmBq8nJbHYI=
github.com/tklauser/numcpus v0.6.1 h1:ng9scYS7az0Bk4OZLvrNXNSAO2Pxr1XXRAPyjhIx+Fk=
github.com/tklauser/numcpus v0.6.1/go.mod h1:1XfjsgE2zo8GVw7POkMbHENHzVg3GzmoZ9fESEdAacY=
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYppBueQtXaqoE=
github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c=
github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU=
github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0=
@@ -261,8 +285,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/lint v0.0.0-20190930215403-16217165b5de/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
@@ -278,11 +302,12 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
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-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.3.0/go.mod h1:MBQ8lrhLObU/6UmLb4fmbmk5OcyYmqtbGd/9yIeKjEE=
golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -293,13 +318,20 @@ 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-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191115151921-52ab43148777/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201204225414-ed752295db88/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/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-20211116061358-0a5406a5449c/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=
@@ -308,9 +340,8 @@ 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.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
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.3.0/go.mod h1:q750SLmJuPmVoN1blW3UFBPREJfb1KmY3vwxfr+nFDA=
@@ -343,8 +374,9 @@ google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI=
google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
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=
-6
View File
@@ -13,7 +13,6 @@ boundary storage-buckets create \
-worker-filter '"minio-access" in "/tags/type"' \
-attr endpoint_url="https://my-minio-instance.dev/s3-api" \
-attr region=REGION \
-attr disable_credential_rotation=true \
-secret access_key_id='KEY' \
-secret secret_access_key='SECRET'
```
@@ -25,11 +24,6 @@ The following `attributes` are valid on a MinIO storage bucket resource:
- `endpoint_url` (string, required): Fully-qualified endpoint pointing to a
MinIO S3 API.
- `region` (string, optional): The region to configure the storage bucket for.
- `disable_credential_rotation` (bool, optional): Controls whether the plugin
will rotate the incoming credentials and manage a new MinIO service account.
If this attribute is set to `false`, or not provided, the plugin will rotate
the incoming credentials, using them to create a new MinIO service account,
then delete the incoming credentials.
### Secrets
+4 -4
View File
@@ -65,11 +65,11 @@ func (sa *StorageSecrets) AsMap() map[string]any {
// Clone returns a new StorageSecrets object with the same state as the incoming
// one.
func (sec *StorageSecrets) Clone() *StorageSecrets {
func (ss *StorageSecrets) Clone() *StorageSecrets {
return &StorageSecrets{
AccessKeyId: sec.AccessKeyId,
SecretAccessKey: sec.SecretAccessKey,
LastRotatedTime: sec.LastRotatedTime,
AccessKeyId: ss.AccessKeyId,
SecretAccessKey: ss.SecretAccessKey,
LastRotatedTime: ss.LastRotatedTime,
}
}
+5 -5
View File
@@ -333,9 +333,9 @@ func TestTestStorageSecretsClone(t *testing.T) {
LastRotatedTime: now,
}
secCl := in.Clone()
require.Equal(t, in.AccessKeyId, secCl.AccessKeyId)
require.Equal(t, in.AccessKeyId, secCl.AccessKeyId)
require.Equal(t, in.LastRotatedTime, secCl.LastRotatedTime)
require.NotSame(t, in, secCl)
ss := in.Clone()
require.Equal(t, in.AccessKeyId, ss.AccessKeyId)
require.Equal(t, in.AccessKeyId, ss.AccessKeyId)
require.Equal(t, in.LastRotatedTime, ss.LastRotatedTime)
require.NotSame(t, in, ss)
}
+31 -20
View File
@@ -60,6 +60,11 @@ func (sp *StoragePlugin) OnCreateStorageBucket(ctx context.Context, req *pb.OnCr
return nil, err
}
err = ensureServiceAccount(ctx, sa, sec)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to ensure service account: %v", err)
}
deleteOldCredsFn := func() error { return nil }
if !sa.DisableCredentialRotation {
newSec, fn, err := rotateCredentials(ctx, bucket.GetBucketName(), sa, sec)
@@ -173,17 +178,22 @@ func (sp *StoragePlugin) OnUpdateStorageBucket(ctx context.Context, req *pb.OnUp
return nil, err
}
err = ensureServiceAccount(ctx, nsa, newSec)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to ensure service account: %s", err)
}
if !nsa.DisableCredentialRotation {
// We have new incoming credentials and we're also rotating,
// therefore we use incoming credentials to create a new service
// account, then delete the incoming credentials. The existing
// persisted credentials have already been scheduled for deletion
// above (if applicable), so we don't need to do it here.
rotatedSec, fn, err := rotateCredentials(ctx, newBucket.GetBucketName(), nsa, newSec)
ss, fn, err := rotateCredentials(ctx, newBucket.GetBucketName(), nsa, newSec)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to rotate minio credentials: %v", err)
}
sec = rotatedSec
sec = ss
deleteRotatedCredsFn = fn
} else {
// We have new incoming credentials but we're not rotating. Set them
@@ -195,8 +205,16 @@ func (sp *StoragePlugin) OnUpdateStorageBucket(ctx context.Context, req *pb.OnUp
} else {
if osa.DisableCredentialRotation && !nsa.DisableCredentialRotation {
// Handle the case where the user enables credential rotation but
// provides no new credentials. This is an error.
return nil, status.Errorf(codes.InvalidArgument, "credential rotation enabled with no new credentials provided")
// provides no new credentials. In this case, we use the existing
// persisted credentials to generate a new service account. The
// persisted credentials are, by definition, not being managed by us
// (credential rotation was disabled beforehand), so don't schedule
// them for deletion.
ss, _, err := rotateCredentials(ctx, newBucket.GetBucketName(), nsa, sec)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to rotate minio credentials: %v", err)
}
sec = ss
}
}
@@ -282,13 +300,9 @@ func (sp *StoragePlugin) ValidatePermissions(ctx context.Context, req *pb.Valida
return nil, err
}
if !sec.LastRotatedTime.IsZero() {
// since these are existing secrets, we only want to validate the
// service account if the credentials have been rotated previously
err = ensureServiceAccount(ctx, sa, sec)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to ensure service account: %v", err)
}
err = ensureServiceAccount(ctx, sa, sec)
if err != nil {
return nil, status.Errorf(codes.InvalidArgument, "failed to ensure service account: %v", err)
}
cl, err := minio.New(sa.EndpointUrl, &minio.Options{
@@ -496,18 +510,13 @@ func (sp *StoragePlugin) PutObject(ctx context.Context, req *pb.PutObjectRequest
return nil, status.Errorf(codes.Internal, "failed to put object into minio: %v", err)
}
resChecksum := res.ChecksumSHA256
if resChecksum == "" {
// We were successful in putting the object but we didn't get a file
// SHA256 checksum from the server. Given that the call was successful,
// assume everything went ok and force the checksum to match so we can
// send it correctly back to Boundary.
resChecksum = checksum
if res.ChecksumSHA256 == "" {
return nil, status.Error(codes.Internal, "missing checksum response from minio")
}
if checksum != resChecksum {
if checksum != res.ChecksumSHA256 {
return nil, status.Error(codes.Internal, "mismatched checksum")
}
decodedChecksum, err := base64.StdEncoding.DecodeString(resChecksum)
decodedChecksum, err := base64.StdEncoding.DecodeString(res.ChecksumSHA256)
if err != nil {
return nil, status.Errorf(codes.Internal, "failed to decode checksum value from minio: %v", err)
}
@@ -572,6 +581,7 @@ func (sp *StoragePlugin) DeleteObjects(ctx context.Context, req *pb.DeleteObject
Recursive: true,
}) {
if obj.Err != nil {
// check if context cancelled ?
return nil, status.Errorf(codes.Unknown, "error iterating minio bucket contents: %v", err)
}
objects = append(objects, obj)
@@ -589,6 +599,7 @@ func (sp *StoragePlugin) DeleteObjects(ctx context.Context, req *pb.DeleteObject
removed := 0
for res := range cl.RemoveObjectsWithResult(ctx, bucket.GetBucketName(), emitter, minio.RemoveObjectsOptions{}) {
if res.Err != nil {
// check if context cancelled ?
return nil, status.Errorf(codes.Unknown, "error deleting minio object(s): %v", err)
}
removed++
+176 -147
View File
@@ -234,6 +234,26 @@ func TestOnCreateStorageBucket(t *testing.T) {
},
expErrMsg: "empty secrets input",
},
{
name: "usingNonServiceAccount",
req: &plugin.OnCreateStorageBucketRequest{
Bucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
},
},
Secrets: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
},
expErrMsg: "The specified service account is not found (Specified service account does not exist)",
},
{
name: "dryRunFail",
req: &plugin.OnCreateStorageBucketRequest{
@@ -303,59 +323,6 @@ func TestOnCreateStorageBucket(t *testing.T) {
}(),
expErrMsg: "failed to rotate minio credentials: failed to create new minio service account: Access Denied",
},
{
name: "credRotationFailNoSvcAcct",
req: func() *plugin.OnCreateStorageBucketRequest {
return &plugin.OnCreateStorageBucketRequest{
Bucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
ConstDisableCredentialRotation: structpb.NewBoolValue(false),
},
},
Secrets: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
}
}(),
expErrMsg: "The specified service account is not found (Specified service account does not exist)",
},
{
name: "successNonServiceAccount",
req: &plugin.OnCreateStorageBucketRequest{
Bucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
ConstDisableCredentialRotation: structpb.NewBoolValue(true),
},
},
Secrets: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
},
expRsp: &plugin.OnCreateStorageBucketResponse{
Persisted: &storagebuckets.StorageBucketPersisted{
Data: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
},
},
{
name: "successNoRotation",
req: &plugin.OnCreateStorageBucketRequest{
@@ -797,6 +764,43 @@ func TestOnUpdateStorageBucket(t *testing.T) {
err: "cannot disable rotation for already-rotated credentials",
errCode: codes.InvalidArgument,
},
{
name: "usingNonServiceAccount",
req: &plugin.OnUpdateStorageBucketRequest{
NewBucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
},
},
Secrets: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
CurrentBucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
},
},
},
Persisted: &storagebuckets.StorageBucketPersisted{
Data: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
},
err: "The specified service account is not found (Specified service account does not exist)",
errCode: codes.InvalidArgument,
},
{
name: "dryRunFail",
req: &plugin.OnUpdateStorageBucketRequest{
@@ -903,7 +907,7 @@ func TestOnUpdateStorageBucket(t *testing.T) {
errCode: codes.InvalidArgument,
},
{
name: "credRotationNoNewCreds",
name: "credRotationFailNoNewCreds",
req: &plugin.OnUpdateStorageBucketRequest{
CurrentBucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
@@ -915,12 +919,32 @@ func TestOnUpdateStorageBucket(t *testing.T) {
},
},
Persisted: &storagebuckets.StorageBucketPersisted{
Data: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.ServiceAccountAccessKeyId),
ConstSecretAccessKey: structpb.NewStringValue(server.ServiceAccountSecretAccessKey),
},
},
Data: func() *structpb.Struct {
creds, err := server.AdminClient.AddServiceAccount(ctx, madmin.AddServiceAccountReq{
Policy: json.RawMessage(`
{
"Statement": [
{
"Action": [
"admin:CreateServiceAccount",
"admin:RemoveServiceAccount"
],
"Effect": "Deny"
}
],
"Version": "2012-10-17"
}
`),
})
require.NoError(t, err)
return &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(creds.AccessKey),
ConstSecretAccessKey: structpb.NewStringValue(creds.SecretKey),
},
}
}(),
},
NewBucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
@@ -932,55 +956,9 @@ func TestOnUpdateStorageBucket(t *testing.T) {
},
},
},
err: "credential rotation enabled with no new credentials provided",
err: "failed to rotate minio credentials: failed to create new minio service account: Access Denied.",
errCode: codes.InvalidArgument,
},
{
name: "successUsingNonServiceAccount",
req: &plugin.OnUpdateStorageBucketRequest{
NewBucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
ConstDisableCredentialRotation: structpb.NewBoolValue(true),
},
},
Secrets: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
CurrentBucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
},
},
},
Persisted: &storagebuckets.StorageBucketPersisted{
Data: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
},
expected: &plugin.OnUpdateStorageBucketResponse{
Persisted: &storagebuckets.StorageBucketPersisted{
Data: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
},
},
{
name: "successNoRotation",
req: &plugin.OnUpdateStorageBucketRequest{
@@ -1133,6 +1111,77 @@ func TestOnUpdateStorageBucket_SuccessDisableCredRotationAndNewCreds(t *testing.
require.Len(t, lsa.Accounts, 2) // Creds in `server` + newCreds.
}
func TestOnUpdateStorageBucket_SuccessEnableCredRotationNoNewCreds(t *testing.T) {
ctx := context.Background()
server := internaltest.NewMinioServer(t)
bucketName := "test"
err := server.Client.MakeBucket(ctx, bucketName, minio.MakeBucketOptions{})
require.NoError(t, err)
persistedCreds, err := server.AdminClient.AddServiceAccount(ctx, madmin.AddServiceAccountReq{})
require.NoError(t, err)
req := &plugin.OnUpdateStorageBucketRequest{
CurrentBucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
ConstDisableCredentialRotation: structpb.NewBoolValue(true),
},
},
},
Persisted: &storagebuckets.StorageBucketPersisted{
Data: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(persistedCreds.AccessKey),
ConstSecretAccessKey: structpb.NewStringValue(persistedCreds.SecretKey),
},
},
},
NewBucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
ConstDisableCredentialRotation: structpb.NewBoolValue(false),
},
},
},
}
// `disable_cred_rotation` disabled -> enable and provide no new creds.
// This should use the existing persisted credentials to generate new ones,
// then use those. The old persisted credentials should not be deleted.
sp := new(StoragePlugin)
rsp, err := sp.OnUpdateStorageBucket(ctx, req)
require.NoError(t, err)
require.NotNil(t, req)
outAccessKeyId, err := values.GetStringValue(rsp.GetPersisted().GetData(), ConstAccessKeyId, true)
require.NoError(t, err)
require.NotEqual(t, persistedCreds.AccessKey, outAccessKeyId)
outSecretAccessKey, err := values.GetStringValue(rsp.GetPersisted().GetData(), ConstSecretAccessKey, true)
require.NoError(t, err)
require.NotEqual(t, persistedCreds.SecretKey, outSecretAccessKey)
lastRotated, err := values.GetTimeValue(rsp.GetPersisted().GetData(), ConstLastRotatedTime)
require.NoError(t, err)
require.False(t, lastRotated.IsZero())
_, err = server.AdminClient.InfoServiceAccount(ctx, persistedCreds.AccessKey)
require.NoError(t, err)
_, err = server.AdminClient.InfoServiceAccount(ctx, outAccessKeyId)
require.NoError(t, err)
lsa, err := server.AdminClient.ListServiceAccounts(ctx, server.RootUsername)
require.NoError(t, err)
require.Len(t, lsa.Accounts, 3) // Creds in `server` + persistedCreds + newly rotated creds.
}
func TestOnUpdateStorageBucket_SuccessEnableCredRotationWithNewCreds(t *testing.T) {
ctx := context.Background()
server := internaltest.NewMinioServer(t)
@@ -1686,6 +1735,26 @@ func TestValidatePermissions(t *testing.T) {
},
expErrMsg: "empty secrets input",
},
{
name: "usingNonServiceAccount",
req: &plugin.ValidatePermissionsRequest{
Bucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
},
},
Secrets: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
},
expErrMsg: "The specified service account is not found (Specified service account does not exist)",
},
{
name: "dryRunFail",
req: &plugin.ValidatePermissionsRequest{
@@ -1713,46 +1782,6 @@ func TestValidatePermissions(t *testing.T) {
},
expErrMsg: "failed to verify provided minio environment: failed to put object",
},
{
name: "rotatedNonServiceAccount",
req: &plugin.ValidatePermissionsRequest{
Bucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
},
},
Secrets: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
ConstLastRotatedTime: structpb.NewStringValue(time.Now().Format(time.RFC3339Nano)),
},
},
},
},
expErrMsg: "The specified service account is not found (Specified service account does not exist)",
},
{
name: "successNonServiceAccount",
req: &plugin.ValidatePermissionsRequest{
Bucket: &storagebuckets.StorageBucket{
BucketName: bucketName,
Attributes: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstEndpointUrl: structpb.NewStringValue("http://" + server.ApiAddr),
},
},
Secrets: &structpb.Struct{
Fields: map[string]*structpb.Value{
ConstAccessKeyId: structpb.NewStringValue(server.RootUsername),
ConstSecretAccessKey: structpb.NewStringValue(server.RootPassword),
},
},
},
},
},
{
name: "success",
req: &plugin.ValidatePermissionsRequest{
+2 -5
View File
@@ -1,6 +1,3 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package storage
import (
@@ -76,9 +73,9 @@ func rotateCredentials(ctx context.Context, bucketName string, sa *StorageAttrib
LastRotatedTime: time.Now(),
}
inCl := inSec.Clone()
inCl, newCl := inSec.Clone(), newSec.Clone()
return newSec, sync.OnceValue(func() error {
ac, err := newMadminClient(sa, inCl)
ac, err := newMadminClient(sa, newCl)
if err != nil {
return fmt.Errorf("failed to create minio admin client: %w", err)
}
+14 -17
View File
@@ -1,6 +1,3 @@
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package storage
import (
@@ -24,13 +21,13 @@ func TestRotateCredentials(t *testing.T) {
tests := []struct {
name string
inSec *StorageSecrets
ss *StorageSecrets
expErrMsg string
credDelErr bool
}{
{
name: "notUsingServiceAccount",
inSec: &StorageSecrets{
ss: &StorageSecrets{
AccessKeyId: server.RootUsername,
SecretAccessKey: server.RootPassword,
},
@@ -38,7 +35,7 @@ func TestRotateCredentials(t *testing.T) {
},
{
name: "addServiceAccountFail",
inSec: func() *StorageSecrets {
ss: func() *StorageSecrets {
creds, err := server.AdminClient.AddServiceAccount(ctx, madmin.AddServiceAccountReq{
Policy: json.RawMessage(`
{
@@ -66,7 +63,7 @@ func TestRotateCredentials(t *testing.T) {
},
{
name: "credentialDeletionFail",
inSec: func() *StorageSecrets {
ss: func() *StorageSecrets {
creds, err := server.AdminClient.AddServiceAccount(ctx, madmin.AddServiceAccountReq{})
require.NoError(t, err)
@@ -79,7 +76,7 @@ func TestRotateCredentials(t *testing.T) {
},
{
name: "success",
inSec: func() *StorageSecrets {
ss: func() *StorageSecrets {
creds, err := server.AdminClient.AddServiceAccount(ctx, madmin.AddServiceAccountReq{})
require.NoError(t, err)
@@ -98,26 +95,26 @@ func TestRotateCredentials(t *testing.T) {
UseSSL: false,
}
outSec, delFn, err := rotateCredentials(context.Background(), bucketName, sa, tt.inSec)
ss, delFn, err := rotateCredentials(context.Background(), bucketName, sa, tt.ss)
if tt.expErrMsg != "" {
require.ErrorContains(t, err, tt.expErrMsg)
require.Nil(t, outSec)
require.Nil(t, ss)
require.Nil(t, delFn)
return
}
require.NoError(t, err)
require.NotNil(t, outSec)
require.NotNil(t, ss)
require.NotNil(t, delFn)
require.NotEqual(t, outSec.AccessKeyId, tt.inSec.AccessKeyId)
require.NotEqual(t, outSec.SecretAccessKey, tt.inSec.SecretAccessKey)
require.NotEmpty(t, outSec.LastRotatedTime)
require.NotEqual(t, ss.AccessKeyId, tt.ss.AccessKeyId)
require.NotEqual(t, ss.SecretAccessKey, tt.ss.SecretAccessKey)
require.NotEmpty(t, ss.LastRotatedTime)
// Ensure old creds still exist since the callback hasn't been
// called. We then make the delete call and finally assert that the
// credential was removed if there was no error when attempting to
// delete.
_, err = server.AdminClient.InfoServiceAccount(ctx, tt.inSec.AccessKeyId)
_, err = server.AdminClient.InfoServiceAccount(ctx, tt.ss.AccessKeyId)
require.NoError(t, err)
if tt.credDelErr {
@@ -125,7 +122,7 @@ func TestRotateCredentials(t *testing.T) {
require.ErrorContains(t, delFn(), "failed to delete minio service account")
require.ErrorContains(t, delFn(), "failed to delete minio service account") // 2nd call should return the same state (due to sync.Once).
_, err := server.AdminClient.InfoServiceAccount(ctx, tt.inSec.AccessKeyId)
_, err := server.AdminClient.InfoServiceAccount(ctx, tt.ss.AccessKeyId)
require.NoError(t, err)
return
} else {
@@ -133,7 +130,7 @@ func TestRotateCredentials(t *testing.T) {
require.NoError(t, delFn()) // 2nd call should return the same state (due to sync.Once).
}
_, err = server.AdminClient.InfoServiceAccount(ctx, tt.inSec.AccessKeyId)
_, err = server.AdminClient.InfoServiceAccount(ctx, tt.ss.AccessKeyId)
require.ErrorContains(t, err, "service account is not found")
})
}