From 989f041658bca62505ef2af40d4600af2733b6c6 Mon Sep 17 00:00:00 2001 From: Lenin Alevski Date: Tue, 6 Sep 2022 08:20:16 -0700 Subject: [PATCH] Support for providing Tenant client certificates (#2294) --- go.mod | 10 +- go.sum | 76 ++++++- models/create_tenant_request.go | 4 +- models/tenant_security_response.go | 57 +++++ models/tls_configuration.go | 97 ++++++-- models/update_tenant_security_request.go | 97 ++++++-- operatorapi/embedded_spec.go | 78 +++++-- operatorapi/tenant_add.go | 38 ++-- operatorapi/tenant_get.go | 2 +- operatorapi/tenants.go | 184 +++++++-------- operatorapi/tenants_helper.go | 14 +- operatorapi/tenants_helper_test.go | 46 +--- operatorapi/tenants_test.go | 141 +++++++++++- .../Tenants/AddTenant/Steps/Encryption.tsx | 8 +- .../Tenants/AddTenant/Steps/Security.tsx | 92 +++++++- .../Tenants/AddTenant/createTenantSlice.ts | 78 +++++-- .../AddTenant/thunks/createTenantThunk.ts | 75 +++---- .../Tenants/TenantDetails/TenantSecurity.tsx | 210 +++++++++++++++--- .../src/screens/Console/Tenants/types.ts | 6 +- swagger-operator.yml | 41 ++-- 20 files changed, 1008 insertions(+), 346 deletions(-) diff --git a/go.mod b/go.mod index b6a6973ec..b3b472ae1 100644 --- a/go.mod +++ b/go.mod @@ -26,14 +26,14 @@ require ( github.com/minio/madmin-go v1.4.26 github.com/minio/mc v0.0.0-20220818165341-8c239d16aa37 github.com/minio/minio-go/v7 v7.0.35 - github.com/minio/operator v0.0.0-20220414212219-ba4c097324b2 + github.com/minio/operator v0.0.0-20220902184351-21e4073132b0 github.com/minio/pkg v1.3.2 github.com/minio/selfupdate v0.5.0 github.com/mitchellh/go-homedir v1.1.0 github.com/rs/xid v1.4.0 github.com/secure-io/sio-go v0.3.1 github.com/stretchr/testify v1.8.0 - github.com/tidwall/gjson v1.14.0 + github.com/tidwall/gjson v1.14.2 github.com/unrolled/secure v1.10.0 golang.org/x/crypto v0.0.0-20220722155217-630584e8d5aa golang.org/x/net v0.0.0-20220722155237-a158d28d115b @@ -46,7 +46,7 @@ require ( ) require ( - cloud.google.com/go v0.81.0 // indirect + cloud.google.com/go v0.99.0 // indirect github.com/Azure/go-autorest v14.2.0+incompatible // indirect github.com/Azure/go-autorest/autorest v0.11.18 // indirect github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect @@ -113,6 +113,7 @@ require ( github.com/mattn/go-runewidth v0.0.13 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 // indirect + github.com/miekg/dns v1.1.48 // indirect github.com/minio/colorjson v1.0.2 // indirect github.com/minio/filepath v1.0.0 // indirect github.com/minio/md5-simd v1.1.2 // indirect @@ -164,11 +165,14 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.8.0 // indirect go.uber.org/zap v1.21.0 // indirect + golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 // indirect golang.org/x/sync v0.0.0-20210220032951-036812b2e83c // indirect golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f // indirect golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect golang.org/x/text v0.3.7 // indirect golang.org/x/time v0.0.0-20220224211638-0e9765cccd65 // indirect + golang.org/x/tools v0.1.10 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto v0.0.0-20220302033224-9aa15565e42a // indirect google.golang.org/grpc v1.44.0 // indirect diff --git a/go.sum b/go.sum index 0f54a5f46..3b997a4a1 100644 --- a/go.sum +++ b/go.sum @@ -17,8 +17,16 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk= cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg= cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= -cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= +cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= +cloud.google.com/go v0.84.0/go.mod h1:RazrYuxIK6Kb7YrzzhPoLmCVzl7Sup4NrbKPg8KHSUM= +cloud.google.com/go v0.87.0/go.mod h1:TpDYlFy7vuLzZMMZ+B6iRiELaY7z/gJPaqbMx6mlWcY= +cloud.google.com/go v0.90.0/go.mod h1:kRX0mNRHe0e2rC6oNakvwQqzyDmg57xJ+SZU1eT2aDQ= +cloud.google.com/go v0.93.3/go.mod h1:8utlLll2EF5XMAV15woO4lSbWQlk8rer9aLOfLh7+YI= +cloud.google.com/go v0.94.1/go.mod h1:qAlAugsXlC+JWO+Bke5vCtc9ONxjQT3drlTTnAplMW4= +cloud.google.com/go v0.97.0/go.mod h1:GF7l59pYBVlXQIBLx3a761cZ41F9bBH3JUlihCt2Udc= +cloud.google.com/go v0.99.0 h1:y/cM2iqGgGi5D5DQZl6D9STN/3dR/Vx5Mp8s752oJTY= +cloud.google.com/go v0.99.0/go.mod h1:w0Xx2nLzqWJPuozYQX+hFfCSI8WioryfRDzkoI/Y2ZA= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= @@ -307,6 +315,7 @@ github.com/golang/mock v1.4.1/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt github.com/golang/mock v1.4.3/go.mod h1:UOMv5ysSaYNkG+OFQykRIcU/QvvxJf3p21QfJ2Bt3cw= github.com/golang/mock v1.4.4/go.mod h1:l3mdAwkq5BuhzHwde/uurv3sEJeZMXNpwsxVWU71h+4= github.com/golang/mock v1.5.0/go.mod h1:CWnOUgYIOo4TcNZ0wHX3YZCqsaM1I1Jvs6v3mP3KVu8= +github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -326,6 +335,7 @@ github.com/golang/protobuf v1.5.1/go.mod h1:DopwsBzvsk0Fs44TXzsVbJyPhcCPeIwnvohx github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= @@ -354,6 +364,7 @@ github.com/google/gofuzz v1.2.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/ github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs= github.com/google/martian/v3 v3.0.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= github.com/google/martian/v3 v3.1.0/go.mod h1:y5Zk1BBys9G+gd6Jrk0W3cC1+ELVxBWuIGO+w/tUAp0= +github.com/google/martian/v3 v3.2.1/go.mod h1:oBOf6HBosgwRXnUGWUB05QECsc6uvmMiJ3+6W4l/CUk= github.com/google/pprof v0.0.0-20181206194817-3ea8567a2e57/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20190515194954-54271f7e092f/go.mod h1:zfwlbNMJ+OItoe0UupaVj+oy1omPYYDuagoSzA8v9mc= github.com/google/pprof v0.0.0-20191218002539-d4f498aebedc/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= @@ -365,6 +376,9 @@ github.com/google/pprof v0.0.0-20201023163331-3e6fc7fc9c4c/go.mod h1:kpwsk12EmLe github.com/google/pprof v0.0.0-20201203190320-1bf35d6f28c2/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210122040257-d980be63207e/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/pprof v0.0.0-20210226084205-cbba55b83ad5/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210601050228-01bbb1931b22/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210609004039-a478d1d731e9/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20210720184732-4bb14d4b1be1/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510 h1:El6M4kTTCOh6aBiKaUGG7oYTSPP8MxqL4YI3kZKwcP4= github.com/google/shlex v0.0.0-20191202100458-e7afc7fbc510/go.mod h1:pupxD2MaaD3pAXIBCelhxNneeOaAeabZDe5s4K6zSpQ= @@ -374,6 +388,8 @@ github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= +github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0= +github.com/googleapis/gax-go/v2 v2.1.1/go.mod h1:hddJymUZASv3XPyGkUpKj8pPO47Rmb0eJc8R6ouapiM= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20220104163920-15ed2e8cf2bd/go.mod h1:cz9oNYuRUWGdHmLF2IodMLkAhcPtXeULvcBNagUrxTI= github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= @@ -524,6 +540,8 @@ github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182aff github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4 h1:NK3O7S5FRD/wj7ORQ5C3Mx1STpyEMuFe+/F0Lakd1Nk= github.com/mb0/glob v0.0.0-20160210091149-1eb79d2de6c4/go.mod h1:FqD3ES5hx6zpzDainDaHgkTIqrPaI9uX4CVWqYZoQjY= github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= +github.com/miekg/dns v1.1.48 h1:Ucfr7IIVyMBz4lRE8qmGUuZ4Wt3/ZGu9hmcMT3Uu4tQ= +github.com/miekg/dns v1.1.48/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/minio/argon2 v1.0.0/go.mod h1:XtOGJ7MjwUJDPtCqqrisx5QwVB/jDx+adQHigJVsQHQ= github.com/minio/cli v1.23.0 h1:hNuf8xi/JU5EJRX+T38e2zcnh2EpdVqs8aH4lNXWe3w= github.com/minio/cli v1.23.0/go.mod h1:bYxnK0uS629N3Bq+AOZZ+6lwF77Sodk4+UL9vNuXhOY= @@ -548,8 +566,8 @@ github.com/minio/md5-simd v1.1.2/go.mod h1:MzdKDxYpY2BT9XQFocsiZf/NKVtR7nkE4RoEp github.com/minio/minio-go/v7 v7.0.23/go.mod h1:ei5JjmxwHaMrgsMrn4U/+Nmg+d8MKS1U2DAn1ou4+Do= github.com/minio/minio-go/v7 v7.0.35 h1:JuPPxWLdxQmNLSaS8AWZnO5HBadeI1xg6FGrEELQEVU= github.com/minio/minio-go/v7 v7.0.35/go.mod h1:nCrRzjoSUQh8hgKKtu3Y708OLvRLtuASMg2/nvmbarw= -github.com/minio/operator v0.0.0-20220414212219-ba4c097324b2 h1:GdjU5qV+Wv0P2Y/TVGRELapzBdph8Vyi6u9VjgvtVIs= -github.com/minio/operator v0.0.0-20220414212219-ba4c097324b2/go.mod h1:4Bo6a+XrBFEfCiiEtB14bw8l/nT3hcvZQKrZGZu27mA= +github.com/minio/operator v0.0.0-20220902184351-21e4073132b0 h1:Ak/IkcWaY/ntGIzpeZIw43hwFKMh1242qIELpk4bVqI= +github.com/minio/operator v0.0.0-20220902184351-21e4073132b0/go.mod h1:pMMJ+WzD3znzYC3Ae/clcKocdSRyenK4kzdstibdafk= github.com/minio/pkg v1.1.20/go.mod h1:Xo7LQshlxGa9shKwJ7NzQbgW4s8T/Wc1cOStR/eUiMY= github.com/minio/pkg v1.3.2 h1:zCpX8jtdF4k6r50sfqVY7rVMsagB4b9BYZaTiqpiknI= github.com/minio/pkg v1.3.2/go.mod h1:mxCLAG+fOGIQr6odQ5Ukqc6qv9Zj6v1d6TD3NP82B7Y= @@ -758,8 +776,8 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= -github.com/tidwall/gjson v1.14.0 h1:6aeJ0bzojgWLa82gDQHcx3S0Lr/O51I9bJ5nv6JFx5w= -github.com/tidwall/gjson v1.14.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.14.2 h1:6BBkirS0rAHjumnjHF6qgy5d2YAJ1TLIaFE2lzfOLqo= +github.com/tidwall/gjson v1.14.2/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= @@ -903,6 +921,7 @@ golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.1/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3 h1:kQgndtyPBW/JIYERgdxfwMYh3AVStj88WQTlNDi2a+o= golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -949,7 +968,9 @@ 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-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= +golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210726213435-c6fcb2dbf985/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210825183410-e898025ed96a/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= @@ -970,6 +991,9 @@ golang.org/x/oauth2 v0.0.0-20210220000619-9bb904979d93/go.mod h1:KelEdhl1UZF7XfJ 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-20210628180205-a41e5a781914/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20210805134026-6f1e6394065a/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/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.0.0-20220411215720-9780585627b5 h1:OSnWWcOd/CtWQC2cYSBgbTSJv3ciqd8r54ySIW2y3RE= @@ -1057,13 +1081,19 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-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-20210603125802-9665404d3644/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-20210616094352-59db8d763f22/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-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210908233432-aa78b53d3365/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211019181941-9d821ace8654/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211124211545-fe61309f8881/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211213223007-03aa0b5f6827/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= @@ -1161,12 +1191,19 @@ golang.org/x/tools v0.0.0-20210105154028-b0ab187a4818/go.mod h1:emZCQorbCU4vsT4f golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210114065538-d78b04bdf963/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.0/go.mod h1:xkSsbof2nBLbhDlRMhhhyNLN/zl3eTqcnHD5viDpcZ0= +golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.3/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.4/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/tools v0.1.6-0.20210726203631-07bc1bf47fb2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.10-0.20220218145154-897bd77cd717/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= +golang.org/x/tools v0.1.10 h1:QjFRCZxdOhBJ/UNgnBZLbNV13DlbnK0quyivTnXJM20= +golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= @@ -1190,6 +1227,15 @@ google.golang.org/api v0.40.0/go.mod h1:fYKFpnQN0DsDSKRVRcQSDQNtqWPfM9i+zNPxepjR google.golang.org/api v0.41.0/go.mod h1:RkxM5lITDfTzmyKFPt+wGrCJbVfniCr2ool8kTBzRTU= google.golang.org/api v0.43.0/go.mod h1:nQsDGjRXMo4lvh5hP0TKqF244gqhGcr/YSIykhUk/94= google.golang.org/api v0.44.0/go.mod h1:EBOGZqzyhtvMDoxwS97ctnh0zUmYY6CxqXsc1AvkYD8= +google.golang.org/api v0.47.0/go.mod h1:Wbvgpq1HddcWVtzsVLyfLp8lDg6AA241LmgIL59tHXo= +google.golang.org/api v0.48.0/go.mod h1:71Pr1vy+TAZRPkPs/xlCf5SsU8WjuAWv1Pfjbtukyy4= +google.golang.org/api v0.50.0/go.mod h1:4bNT5pAuq5ji4SRZm+5QIkjny9JAyVD/3gaSihNefaw= +google.golang.org/api v0.51.0/go.mod h1:t4HdrdoNgyN5cbEfm7Lum0lcLDLiise1F8qDKX00sOU= +google.golang.org/api v0.54.0/go.mod h1:7C4bFFOvVDGXjfDTAsgGwDgAxRDeQ4X8NvUedIt6z3k= +google.golang.org/api v0.55.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.56.0/go.mod h1:38yMfeP1kfjsl8isn0tliTjIb1rJXcQi4UXlbqivdVE= +google.golang.org/api v0.57.0/go.mod h1:dVPlbZyBo2/OjBpmvNdpn2GRm6rPy75jyU7bmhdrMgI= +google.golang.org/api v0.61.0/go.mod h1:xQRti5UdCmoCEqFxcz93fTl338AVqDgyaDRuOZ3hg9I= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -1241,8 +1287,24 @@ google.golang.org/genproto v0.0.0-20210303154014-9728d6b83eeb/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20210310155132-4ce2db91004e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210319143718-93e7006c17a6/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20210402141018-6c239bbf2bb1/go.mod h1:9lPAdzaEmUacj36I+k7YKbEc5CXzPIeORRgDAUOu28A= +google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQyzQSnHPnZ/vqoCdDmzH28fzWByN9asMeM8A= google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210604141403-392c879c8b08/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210608205507-b6d2f5bf0d7d/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= +google.golang.org/genproto v0.0.0-20210624195500-8bfb893ecb84/go.mod h1:SzzZ/N+nwJDaO1kznhnlzqS8ocJICar6hYhVyhi++24= +google.golang.org/genproto v0.0.0-20210713002101-d411969a0d9a/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210716133855-ce7ef5c701ea/go.mod h1:AxrInvYm1dci+enl5hChSFPOmmUF1+uAa/UsgNRWd7k= +google.golang.org/genproto v0.0.0-20210728212813-7823e685a01f/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210805201207-89edb61ffb67/go.mod h1:ob2IJxKrgPT52GcgX759i1sleT07tiKowYBGbczaW48= +google.golang.org/genproto v0.0.0-20210813162853-db860fec028c/go.mod h1:cFeNkxwySK631ADgubI+/XFU/xp8FD5KIVV4rj8UC5w= +google.golang.org/genproto v0.0.0-20210821163610-241b8fcbd6c8/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210828152312-66f60bf46e71/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= google.golang.org/genproto v0.0.0-20210831024726-fe130286e0e2/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210903162649-d08c68adba83/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210909211513-a8c4777a87af/go.mod h1:eFjDcFEctNawg4eG61bRv87N7iHBWyVhJu7u1kqDUXY= +google.golang.org/genproto v0.0.0-20210924002016-3dee208752a0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211118181313-81c1377c94b1/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= +google.golang.org/genproto v0.0.0-20211206160659-862468c7d6e0/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220107163113-42d7afdf6368/go.mod h1:5CzLGKJ67TSI2B9POpiiyGha0AjJvZIUgRMt1dSmuhc= google.golang.org/genproto v0.0.0-20220302033224-9aa15565e42a h1:uqouglH745GoGeZ1YFZbPBiu961tgi/9Qm5jaorajjQ= google.golang.org/genproto v0.0.0-20220302033224-9aa15565e42a/go.mod h1:kGP+zUP2Ddo0ayMi4YuN7C3WZyJvGLZRh8Z5wnAqvEI= @@ -1266,10 +1328,14 @@ google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAG google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.36.1/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= +google.golang.org/grpc v1.39.0/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= +google.golang.org/grpc v1.39.1/go.mod h1:PImNr+rS9TWYb2O4/emRugxiyHZ5JyHW5F+RPnDzfrE= google.golang.org/grpc v1.40.0/go.mod h1:ogyxbiOoUXAkP+4+xa6PZSE9DZgIHtSpzjDTB9KAK34= google.golang.org/grpc v1.44.0 h1:weqSxi/TMs1SqFRMHCtBgXRs8k3X39QIDEZ0pRcttUg= google.golang.org/grpc v1.44.0/go.mod h1:k+4IHHFw41K8+bbowsex27ge2rCb65oeWqe4jJ590SU= +google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/models/create_tenant_request.go b/models/create_tenant_request.go index 98d1253da..e37de0f04 100644 --- a/models/create_tenant_request.go +++ b/models/create_tenant_request.go @@ -85,8 +85,8 @@ type CreateTenantRequest struct { // log search configuration LogSearchConfiguration *LogSearchConfiguration `json:"logSearchConfiguration,omitempty"` - // mounth path - MounthPath string `json:"mounth_path,omitempty"` + // mount path + MountPath string `json:"mount_path,omitempty"` // name // Required: true diff --git a/models/tenant_security_response.go b/models/tenant_security_response.go index b36579157..c7cdd0e38 100644 --- a/models/tenant_security_response.go +++ b/models/tenant_security_response.go @@ -175,6 +175,9 @@ func (m *TenantSecurityResponse) UnmarshalBinary(b []byte) error { // swagger:model TenantSecurityResponseCustomCertificates type TenantSecurityResponseCustomCertificates struct { + // client + Client []*CertificateInfo `json:"client"` + // minio Minio []*CertificateInfo `json:"minio"` @@ -186,6 +189,10 @@ type TenantSecurityResponseCustomCertificates struct { func (m *TenantSecurityResponseCustomCertificates) Validate(formats strfmt.Registry) error { var res []error + if err := m.validateClient(formats); err != nil { + res = append(res, err) + } + if err := m.validateMinio(formats); err != nil { res = append(res, err) } @@ -200,6 +207,32 @@ func (m *TenantSecurityResponseCustomCertificates) Validate(formats strfmt.Regis return nil } +func (m *TenantSecurityResponseCustomCertificates) validateClient(formats strfmt.Registry) error { + if swag.IsZero(m.Client) { // not required + return nil + } + + for i := 0; i < len(m.Client); i++ { + if swag.IsZero(m.Client[i]) { // not required + continue + } + + if m.Client[i] != nil { + if err := m.Client[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("customCertificates" + "." + "client" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("customCertificates" + "." + "client" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + func (m *TenantSecurityResponseCustomCertificates) validateMinio(formats strfmt.Registry) error { if swag.IsZero(m.Minio) { // not required return nil @@ -256,6 +289,10 @@ func (m *TenantSecurityResponseCustomCertificates) validateMinioCAs(formats strf func (m *TenantSecurityResponseCustomCertificates) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error + if err := m.contextValidateClient(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateMinio(ctx, formats); err != nil { res = append(res, err) } @@ -270,6 +307,26 @@ func (m *TenantSecurityResponseCustomCertificates) ContextValidate(ctx context.C return nil } +func (m *TenantSecurityResponseCustomCertificates) contextValidateClient(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.Client); i++ { + + if m.Client[i] != nil { + if err := m.Client[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("customCertificates" + "." + "client" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("customCertificates" + "." + "client" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + func (m *TenantSecurityResponseCustomCertificates) contextValidateMinio(ctx context.Context, formats strfmt.Registry) error { for i := 0; i < len(m.Minio); i++ { diff --git a/models/tls_configuration.go b/models/tls_configuration.go index a15e102ce..5d6d3d45d 100644 --- a/models/tls_configuration.go +++ b/models/tls_configuration.go @@ -36,18 +36,25 @@ import ( // swagger:model tlsConfiguration type TLSConfiguration struct { - // ca certificates - CaCertificates []string `json:"ca_certificates"` + // minio c as certificates + MinioCAsCertificates []string `json:"minioCAsCertificates"` - // minio - Minio []*KeyPairConfiguration `json:"minio"` + // minio client certificates + MinioClientCertificates []*KeyPairConfiguration `json:"minioClientCertificates"` + + // minio server certificates + MinioServerCertificates []*KeyPairConfiguration `json:"minioServerCertificates"` } // Validate validates this tls configuration func (m *TLSConfiguration) Validate(formats strfmt.Registry) error { var res []error - if err := m.validateMinio(formats); err != nil { + if err := m.validateMinioClientCertificates(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMinioServerCertificates(formats); err != nil { res = append(res, err) } @@ -57,22 +64,48 @@ func (m *TLSConfiguration) Validate(formats strfmt.Registry) error { return nil } -func (m *TLSConfiguration) validateMinio(formats strfmt.Registry) error { - if swag.IsZero(m.Minio) { // not required +func (m *TLSConfiguration) validateMinioClientCertificates(formats strfmt.Registry) error { + if swag.IsZero(m.MinioClientCertificates) { // not required return nil } - for i := 0; i < len(m.Minio); i++ { - if swag.IsZero(m.Minio[i]) { // not required + for i := 0; i < len(m.MinioClientCertificates); i++ { + if swag.IsZero(m.MinioClientCertificates[i]) { // not required continue } - if m.Minio[i] != nil { - if err := m.Minio[i].Validate(formats); err != nil { + if m.MinioClientCertificates[i] != nil { + if err := m.MinioClientCertificates[i].Validate(formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("minio" + "." + strconv.Itoa(i)) + return ve.ValidateName("minioClientCertificates" + "." + strconv.Itoa(i)) } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("minio" + "." + strconv.Itoa(i)) + return ce.ValidateName("minioClientCertificates" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +func (m *TLSConfiguration) validateMinioServerCertificates(formats strfmt.Registry) error { + if swag.IsZero(m.MinioServerCertificates) { // not required + return nil + } + + for i := 0; i < len(m.MinioServerCertificates); i++ { + if swag.IsZero(m.MinioServerCertificates[i]) { // not required + continue + } + + if m.MinioServerCertificates[i] != nil { + if err := m.MinioServerCertificates[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("minioServerCertificates" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("minioServerCertificates" + "." + strconv.Itoa(i)) } return err } @@ -87,7 +120,11 @@ func (m *TLSConfiguration) validateMinio(formats strfmt.Registry) error { func (m *TLSConfiguration) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error - if err := m.contextValidateMinio(ctx, formats); err != nil { + if err := m.contextValidateMinioClientCertificates(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateMinioServerCertificates(ctx, formats); err != nil { res = append(res, err) } @@ -97,16 +134,36 @@ func (m *TLSConfiguration) ContextValidate(ctx context.Context, formats strfmt.R return nil } -func (m *TLSConfiguration) contextValidateMinio(ctx context.Context, formats strfmt.Registry) error { +func (m *TLSConfiguration) contextValidateMinioClientCertificates(ctx context.Context, formats strfmt.Registry) error { - for i := 0; i < len(m.Minio); i++ { + for i := 0; i < len(m.MinioClientCertificates); i++ { - if m.Minio[i] != nil { - if err := m.Minio[i].ContextValidate(ctx, formats); err != nil { + if m.MinioClientCertificates[i] != nil { + if err := m.MinioClientCertificates[i].ContextValidate(ctx, formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("minio" + "." + strconv.Itoa(i)) + return ve.ValidateName("minioClientCertificates" + "." + strconv.Itoa(i)) } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("minio" + "." + strconv.Itoa(i)) + return ce.ValidateName("minioClientCertificates" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +func (m *TLSConfiguration) contextValidateMinioServerCertificates(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.MinioServerCertificates); i++ { + + if m.MinioServerCertificates[i] != nil { + if err := m.MinioServerCertificates[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("minioServerCertificates" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("minioServerCertificates" + "." + strconv.Itoa(i)) } return err } diff --git a/models/update_tenant_security_request.go b/models/update_tenant_security_request.go index 07b19fe94..0bb631569 100644 --- a/models/update_tenant_security_request.go +++ b/models/update_tenant_security_request.go @@ -175,11 +175,14 @@ func (m *UpdateTenantSecurityRequest) UnmarshalBinary(b []byte) error { // swagger:model UpdateTenantSecurityRequestCustomCertificates type UpdateTenantSecurityRequestCustomCertificates struct { - // minio - Minio []*KeyPairConfiguration `json:"minio"` + // minio c as certificates + MinioCAsCertificates []string `json:"minioCAsCertificates"` - // minio c as - MinioCAs []string `json:"minioCAs"` + // minio client certificates + MinioClientCertificates []*KeyPairConfiguration `json:"minioClientCertificates"` + + // minio server certificates + MinioServerCertificates []*KeyPairConfiguration `json:"minioServerCertificates"` // secrets to be deleted SecretsToBeDeleted []string `json:"secretsToBeDeleted"` @@ -189,7 +192,11 @@ type UpdateTenantSecurityRequestCustomCertificates struct { func (m *UpdateTenantSecurityRequestCustomCertificates) Validate(formats strfmt.Registry) error { var res []error - if err := m.validateMinio(formats); err != nil { + if err := m.validateMinioClientCertificates(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMinioServerCertificates(formats); err != nil { res = append(res, err) } @@ -199,22 +206,48 @@ func (m *UpdateTenantSecurityRequestCustomCertificates) Validate(formats strfmt. return nil } -func (m *UpdateTenantSecurityRequestCustomCertificates) validateMinio(formats strfmt.Registry) error { - if swag.IsZero(m.Minio) { // not required +func (m *UpdateTenantSecurityRequestCustomCertificates) validateMinioClientCertificates(formats strfmt.Registry) error { + if swag.IsZero(m.MinioClientCertificates) { // not required return nil } - for i := 0; i < len(m.Minio); i++ { - if swag.IsZero(m.Minio[i]) { // not required + for i := 0; i < len(m.MinioClientCertificates); i++ { + if swag.IsZero(m.MinioClientCertificates[i]) { // not required continue } - if m.Minio[i] != nil { - if err := m.Minio[i].Validate(formats); err != nil { + if m.MinioClientCertificates[i] != nil { + if err := m.MinioClientCertificates[i].Validate(formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("customCertificates" + "." + "minio" + "." + strconv.Itoa(i)) + return ve.ValidateName("customCertificates" + "." + "minioClientCertificates" + "." + strconv.Itoa(i)) } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("customCertificates" + "." + "minio" + "." + strconv.Itoa(i)) + return ce.ValidateName("customCertificates" + "." + "minioClientCertificates" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +func (m *UpdateTenantSecurityRequestCustomCertificates) validateMinioServerCertificates(formats strfmt.Registry) error { + if swag.IsZero(m.MinioServerCertificates) { // not required + return nil + } + + for i := 0; i < len(m.MinioServerCertificates); i++ { + if swag.IsZero(m.MinioServerCertificates[i]) { // not required + continue + } + + if m.MinioServerCertificates[i] != nil { + if err := m.MinioServerCertificates[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("customCertificates" + "." + "minioServerCertificates" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("customCertificates" + "." + "minioServerCertificates" + "." + strconv.Itoa(i)) } return err } @@ -229,7 +262,11 @@ func (m *UpdateTenantSecurityRequestCustomCertificates) validateMinio(formats st func (m *UpdateTenantSecurityRequestCustomCertificates) ContextValidate(ctx context.Context, formats strfmt.Registry) error { var res []error - if err := m.contextValidateMinio(ctx, formats); err != nil { + if err := m.contextValidateMinioClientCertificates(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateMinioServerCertificates(ctx, formats); err != nil { res = append(res, err) } @@ -239,16 +276,36 @@ func (m *UpdateTenantSecurityRequestCustomCertificates) ContextValidate(ctx cont return nil } -func (m *UpdateTenantSecurityRequestCustomCertificates) contextValidateMinio(ctx context.Context, formats strfmt.Registry) error { +func (m *UpdateTenantSecurityRequestCustomCertificates) contextValidateMinioClientCertificates(ctx context.Context, formats strfmt.Registry) error { - for i := 0; i < len(m.Minio); i++ { + for i := 0; i < len(m.MinioClientCertificates); i++ { - if m.Minio[i] != nil { - if err := m.Minio[i].ContextValidate(ctx, formats); err != nil { + if m.MinioClientCertificates[i] != nil { + if err := m.MinioClientCertificates[i].ContextValidate(ctx, formats); err != nil { if ve, ok := err.(*errors.Validation); ok { - return ve.ValidateName("customCertificates" + "." + "minio" + "." + strconv.Itoa(i)) + return ve.ValidateName("customCertificates" + "." + "minioClientCertificates" + "." + strconv.Itoa(i)) } else if ce, ok := err.(*errors.CompositeError); ok { - return ce.ValidateName("customCertificates" + "." + "minio" + "." + strconv.Itoa(i)) + return ce.ValidateName("customCertificates" + "." + "minioClientCertificates" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +func (m *UpdateTenantSecurityRequestCustomCertificates) contextValidateMinioServerCertificates(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.MinioServerCertificates); i++ { + + if m.MinioServerCertificates[i] != nil { + if err := m.MinioServerCertificates[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("customCertificates" + "." + "minioServerCertificates" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("customCertificates" + "." + "minioServerCertificates" + "." + strconv.Itoa(i)) } return err } diff --git a/operatorapi/embedded_spec.go b/operatorapi/embedded_spec.go index 8e4ef8429..c0a9db259 100644 --- a/operatorapi/embedded_spec.go +++ b/operatorapi/embedded_spec.go @@ -2651,7 +2651,7 @@ func init() { "logSearchConfiguration": { "$ref": "#/definitions/logSearchConfiguration" }, - "mounth_path": { + "mount_path": { "type": "string" }, "name": { @@ -4757,6 +4757,12 @@ func init() { "customCertificates": { "type": "object", "properties": { + "client": { + "type": "array", + "items": { + "$ref": "#/definitions/certificateInfo" + } + }, "minio": { "type": "array", "items": { @@ -4861,13 +4867,19 @@ func init() { "tlsConfiguration": { "type": "object", "properties": { - "ca_certificates": { + "minioCAsCertificates": { "type": "array", "items": { "type": "string" } }, - "minio": { + "minioClientCertificates": { + "type": "array", + "items": { + "$ref": "#/definitions/keyPairConfiguration" + } + }, + "minioServerCertificates": { "type": "array", "items": { "$ref": "#/definitions/keyPairConfiguration" @@ -4930,16 +4942,22 @@ func init() { "customCertificates": { "type": "object", "properties": { - "minio": { + "minioCAsCertificates": { + "type": "array", + "items": { + "type": "string" + } + }, + "minioClientCertificates": { "type": "array", "items": { "$ref": "#/definitions/keyPairConfiguration" } }, - "minioCAs": { + "minioServerCertificates": { "type": "array", "items": { - "type": "string" + "$ref": "#/definitions/keyPairConfiguration" } }, "secretsToBeDeleted": { @@ -8128,6 +8146,12 @@ func init() { "TenantSecurityResponseCustomCertificates": { "type": "object", "properties": { + "client": { + "type": "array", + "items": { + "$ref": "#/definitions/certificateInfo" + } + }, "minio": { "type": "array", "items": { @@ -8166,16 +8190,22 @@ func init() { "UpdateTenantSecurityRequestCustomCertificates": { "type": "object", "properties": { - "minio": { + "minioCAsCertificates": { + "type": "array", + "items": { + "type": "string" + } + }, + "minioClientCertificates": { "type": "array", "items": { "$ref": "#/definitions/keyPairConfiguration" } }, - "minioCAs": { + "minioServerCertificates": { "type": "array", "items": { - "type": "string" + "$ref": "#/definitions/keyPairConfiguration" } }, "secretsToBeDeleted": { @@ -8576,7 +8606,7 @@ func init() { "logSearchConfiguration": { "$ref": "#/definitions/logSearchConfiguration" }, - "mounth_path": { + "mount_path": { "type": "string" }, "name": { @@ -10535,6 +10565,12 @@ func init() { "customCertificates": { "type": "object", "properties": { + "client": { + "type": "array", + "items": { + "$ref": "#/definitions/certificateInfo" + } + }, "minio": { "type": "array", "items": { @@ -10639,13 +10675,19 @@ func init() { "tlsConfiguration": { "type": "object", "properties": { - "ca_certificates": { + "minioCAsCertificates": { "type": "array", "items": { "type": "string" } }, - "minio": { + "minioClientCertificates": { + "type": "array", + "items": { + "$ref": "#/definitions/keyPairConfiguration" + } + }, + "minioServerCertificates": { "type": "array", "items": { "$ref": "#/definitions/keyPairConfiguration" @@ -10708,16 +10750,22 @@ func init() { "customCertificates": { "type": "object", "properties": { - "minio": { + "minioCAsCertificates": { + "type": "array", + "items": { + "type": "string" + } + }, + "minioClientCertificates": { "type": "array", "items": { "$ref": "#/definitions/keyPairConfiguration" } }, - "minioCAs": { + "minioServerCertificates": { "type": "array", "items": { - "type": "string" + "$ref": "#/definitions/keyPairConfiguration" } }, "secretsToBeDeleted": { diff --git a/operatorapi/tenant_add.go b/operatorapi/tenant_add.go index 658cf9898..9a997ad03 100644 --- a/operatorapi/tenant_add.go +++ b/operatorapi/tenant_add.go @@ -256,7 +256,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre } } - isEncryptionEnabled := false + canEncryptionBeEnabled := false if tenantReq.EnableTLS != nil { // if enableTLS is defined in the create tenant request we assign the value @@ -264,25 +264,35 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre minInst.Spec.RequestAutoCert = tenantReq.EnableTLS if *tenantReq.EnableTLS { // requestAutoCert is enabled, MinIO will be deployed with TLS enabled and encryption can be enabled - isEncryptionEnabled = true + canEncryptionBeEnabled = true } } - // External TLS certificates for MinIO - if tenantReq.TLS != nil && len(tenantReq.TLS.Minio) > 0 { - isEncryptionEnabled = true + // External server TLS certificates for MinIO + if tenantReq.TLS != nil && len(tenantReq.TLS.MinioServerCertificates) > 0 { + canEncryptionBeEnabled = true // Certificates used by the MinIO instance - externalCertSecretName := fmt.Sprintf("%s-instance-external-certificates", secretName) - externalCertSecret, err := createOrReplaceExternalCertSecrets(ctx, &k8sClient, ns, tenantReq.TLS.Minio, externalCertSecretName, tenantName) + externalCertSecretName := fmt.Sprintf("%s-external-server-certificate", tenantName) + externalCertSecret, err := createOrReplaceExternalCertSecrets(ctx, &k8sClient, ns, tenantReq.TLS.MinioServerCertificates, externalCertSecretName, tenantName) if err != nil { return nil, restapi.ErrorWithContext(ctx, err) } minInst.Spec.ExternalCertSecret = externalCertSecret } + // External client TLS certificates for MinIO + if tenantReq.TLS != nil && len(tenantReq.TLS.MinioClientCertificates) > 0 { + // Client certificates used by the MinIO instance + externalClientCertSecretName := fmt.Sprintf("%s-external-client-certificate", tenantName) + externalClientCertSecret, err := createOrReplaceExternalCertSecrets(ctx, &k8sClient, ns, tenantReq.TLS.MinioClientCertificates, externalClientCertSecretName, tenantName) + if err != nil { + return nil, restapi.ErrorWithContext(ctx, err) + } + minInst.Spec.ExternalClientCertSecrets = externalClientCertSecret + } // If encryption configuration is present and TLS will be enabled (using AutoCert or External certificates) - if tenantReq.Encryption != nil && isEncryptionEnabled { + if tenantReq.Encryption != nil && canEncryptionBeEnabled { // KES client mTLSCertificates used by MinIO instance if tenantReq.Encryption.Client != nil { - tenantExternalClientCertSecretName := fmt.Sprintf("%s-tenant-external-client-cert", secretName) + tenantExternalClientCertSecretName := fmt.Sprintf("%s-external-client-certificate-kes", tenantName) certificates := []*models.KeyPairConfiguration{tenantReq.Encryption.Client} certificateSecrets, err := createOrReplaceExternalCertSecrets(ctx, &k8sClient, ns, certificates, tenantExternalClientCertSecretName, tenantName) if err != nil { @@ -312,15 +322,15 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre } } // External TLS CA certificates for MinIO - if tenantReq.TLS != nil && len(tenantReq.TLS.CaCertificates) > 0 { + if tenantReq.TLS != nil && len(tenantReq.TLS.MinioCAsCertificates) > 0 { var caCertificates []tenantSecret - for i, caCertificate := range tenantReq.TLS.CaCertificates { + for i, caCertificate := range tenantReq.TLS.MinioCAsCertificates { certificateContent, err := base64.StdEncoding.DecodeString(caCertificate) if err != nil { return nil, restapi.ErrorWithContext(ctx, restapi.ErrDefault, nil, err) } caCertificates = append(caCertificates, tenantSecret{ - Name: fmt.Sprintf("ca-certificate-%d", i), + Name: fmt.Sprintf("%s-ca-certificate-%d", tenantName, i), Content: map[string][]byte{ "public.crt": certificateContent, }, @@ -353,8 +363,8 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre } // Set Mount Path if provided - if tenantReq.MounthPath != "" { - minInst.Spec.Mountpath = tenantReq.MounthPath + if tenantReq.MountPath != "" { + minInst.Spec.Mountpath = tenantReq.MountPath } // We accept either `image_pull_secret` or the individual details of the `image_registry` but not both diff --git a/operatorapi/tenant_get.go b/operatorapi/tenant_get.go index 6a5869900..fcea5f263 100644 --- a/operatorapi/tenant_get.go +++ b/operatorapi/tenant_get.go @@ -71,7 +71,7 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten // detect if encryption is enabled info.EncryptionEnabled = minTenant.HasKESEnabled() || tenantConfiguration["MINIO_KMS_SECRET_KEY"] != "" - info.LogEnabled = minTenant.HasLogEnabled() + info.LogEnabled = minTenant.HasLogSearchAPIEnabled() info.MonitoringEnabled = minTenant.HasPrometheusEnabled() info.IdpAdEnabled = ldapEnabled info.IdpOidcEnabled = oidcEnabled diff --git a/operatorapi/tenants.go b/operatorapi/tenants.go index 1b1745ec7..669af75ed 100644 --- a/operatorapi/tenants.go +++ b/operatorapi/tenants.go @@ -614,65 +614,70 @@ func parseTenantCertificates(ctx context.Context, clientSet K8sClientI, namespac if err != nil { return nil, err } - if v, ok := secretTypePublicKeyNameMap[secret.Type]; ok { publicKey = v } - - // Extract public key from certificate TLS secret - if rawCert, ok := keyPair.Data[publicKey]; ok { - var blocks []byte - for { - var block *pem.Block - block, rawCert = pem.Decode(rawCert) - if block == nil { - break - } - if block.Type == "CERTIFICATE" { - blocks = append(blocks, block.Bytes...) + var rawCert []byte + if _, ok := keyPair.Data[publicKey]; !ok { + return nil, fmt.Errorf("public key: %v not found inside certificate secret %v", publicKey, secret.Name) + } + rawCert = keyPair.Data[publicKey] + var blocks []byte + for { + var block *pem.Block + block, rawCert = pem.Decode(rawCert) + if block == nil { + break + } + if block.Type == "CERTIFICATE" { + blocks = append(blocks, block.Bytes...) + } + } + // parse all certificates we found on this k8s secret + certs, err := x509.ParseCertificates(blocks) + if err != nil { + return nil, err + } + for _, cert := range certs { + var domains []string + if cert.Subject.CommonName != "" { + domains = append(domains, cert.Subject.CommonName) + } + // append certificate domain names + if len(cert.DNSNames) > 0 { + domains = append(domains, cert.DNSNames...) + } + // append certificate IPs + if len(cert.IPAddresses) > 0 { + for _, ip := range cert.IPAddresses { + domains = append(domains, ip.String()) } } - // parse all certificates we found on this k8s secret - certs, err := x509.ParseCertificates(blocks) - if err != nil { - return nil, err - } - for _, cert := range certs { - var domains []string - if cert.Subject.CommonName != "" { - domains = append(domains, cert.Subject.CommonName) - } - // append certificate domain names - if len(cert.DNSNames) > 0 { - domains = append(domains, cert.DNSNames...) - } - // append certificate IPs - if len(cert.IPAddresses) > 0 { - for _, ip := range cert.IPAddresses { - domains = append(domains, ip.String()) - } - } - certificates = append(certificates, &models.CertificateInfo{ - SerialNumber: cert.SerialNumber.String(), - Name: secret.Name, - Domains: domains, - Expiry: cert.NotAfter.Format(time.RFC3339), - }) - } + certificates = append(certificates, &models.CertificateInfo{ + SerialNumber: cert.SerialNumber.String(), + Name: secret.Name, + Domains: domains, + Expiry: cert.NotAfter.Format(time.RFC3339), + }) } } return certificates, nil } func getTenantSecurity(ctx context.Context, clientSet K8sClientI, tenant *miniov2.Tenant) (response *models.TenantSecurityResponse, err error) { - var minioExternalCertificates []*models.CertificateInfo + var minioExternalServerCertificates []*models.CertificateInfo + var minioExternalClientCertificates []*models.CertificateInfo var minioExternalCaCertificates []*models.CertificateInfo var tenantSecurityContext *models.SecurityContext - // Certificates used by MinIO server - if minioExternalCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.ExternalCertSecret); err != nil { + // Server certificates used by MinIO + if minioExternalServerCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.ExternalCertSecret); err != nil { return nil, err } - // CA Certificates used by MinIO server + // Client certificates used by MinIO + if minioExternalClientCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.ExternalClientCertSecrets); err != nil { + return nil, err + } + // CA Certificates used by MinIO if minioExternalCaCertificates, err = parseTenantCertificates(ctx, clientSet, tenant.Namespace, tenant.Spec.ExternalCaCertSecret); err != nil { return nil, err } @@ -683,8 +688,9 @@ func getTenantSecurity(ctx context.Context, clientSet K8sClientI, tenant *miniov return &models.TenantSecurityResponse{ AutoCert: tenant.AutoCert(), CustomCertificates: &models.TenantSecurityResponseCustomCertificates{ - Minio: minioExternalCertificates, + Minio: minioExternalServerCertificates, MinioCAs: minioExternalCaCertificates, + Client: minioExternalClientCertificates, }, SecurityContext: tenantSecurityContext, }, nil @@ -857,13 +863,6 @@ func updateTenantIdentityProvider(ctx context.Context, operatorClient OperatorCl if err != nil { return err } - // restart all MinIO pods at the same time - err = client.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", miniov2.TenantLabel, tenant.Name), - }) - if err != nil { - return err - } return nil } @@ -1034,47 +1033,55 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c } // Update AutoCert minInst.Spec.RequestAutoCert = ¶ms.Body.AutoCert - var newMinIOExternalCertSecret []*miniov2.LocalCertificateReference - var newMinIOExternalCaCertSecret []*miniov2.LocalCertificateReference - // Remove Certificate Secrets from MinIO (Tenant.Spec.ExternalCertSecret) - for _, certificate := range minInst.Spec.ExternalCertSecret { - skip := false - for _, certificateToBeDeleted := range params.Body.CustomCertificates.SecretsToBeDeleted { - if certificate.Name == certificateToBeDeleted { - skip = true - break + var newExternalCertSecret []*miniov2.LocalCertificateReference + var newExternalClientCertSecrets []*miniov2.LocalCertificateReference + var newExternalCaCertSecret []*miniov2.LocalCertificateReference + secretsToBeRemoved := map[string]bool{} + + if params.Body.CustomCertificates != nil { + // Copy certificate secrets to be deleted into map + for _, secret := range params.Body.CustomCertificates.SecretsToBeDeleted { + secretsToBeRemoved[secret] = true + } + + // Remove certificates from Tenant.Spec.ExternalCertSecret + for _, certificate := range minInst.Spec.ExternalCertSecret { + if _, ok := secretsToBeRemoved[certificate.Name]; !ok { + newExternalCertSecret = append(newExternalCertSecret, certificate) } } - if skip { - continue - } - newMinIOExternalCertSecret = append(newMinIOExternalCertSecret, certificate) - } - // Remove Certificate Secrets from MinIO CAs (Tenant.Spec.ExternalCaCertSecret) - for _, certificate := range minInst.Spec.ExternalCaCertSecret { - skip := false - for _, certificateToBeDeleted := range params.Body.CustomCertificates.SecretsToBeDeleted { - if certificate.Name == certificateToBeDeleted { - skip = true - break + // Remove certificates from Tenant.Spec.ExternalClientCertSecrets + for _, certificate := range minInst.Spec.ExternalClientCertSecrets { + if _, ok := secretsToBeRemoved[certificate.Name]; !ok { + newExternalClientCertSecrets = append(newExternalClientCertSecrets, certificate) } } - if skip { - continue + // Remove certificates from Tenant.Spec.ExternalCaCertSecret + for _, certificate := range minInst.Spec.ExternalCaCertSecret { + if _, ok := secretsToBeRemoved[certificate.Name]; !ok { + newExternalCaCertSecret = append(newExternalCaCertSecret, certificate) + } } - newMinIOExternalCaCertSecret = append(newMinIOExternalCaCertSecret, certificate) + } - // Create new Certificate Secrets for MinIO secretName := fmt.Sprintf("%s-%s", minInst.Name, strings.ToLower(utils.RandomCharString(5))) - externalCertSecretName := fmt.Sprintf("%s-external-certificates", secretName) - externalCertSecrets, err := createOrReplaceExternalCertSecrets(ctx, client, minInst.Namespace, params.Body.CustomCertificates.Minio, externalCertSecretName, minInst.Name) + // Create new Server Certificate Secrets for MinIO + externalServerCertSecretName := fmt.Sprintf("%s-external-server-certificate", secretName) + externalServerCertSecrets, err := createOrReplaceExternalCertSecrets(ctx, client, minInst.Namespace, params.Body.CustomCertificates.MinioServerCertificates, externalServerCertSecretName, minInst.Name) if err != nil { return err } - newMinIOExternalCertSecret = append(newMinIOExternalCertSecret, externalCertSecrets...) + newExternalCertSecret = append(newExternalCertSecret, externalServerCertSecrets...) + // Create new Client Certificate Secrets for MinIO + externalClientCertSecretName := fmt.Sprintf("%s-external-client-certificate", secretName) + externalClientCertSecrets, err := createOrReplaceExternalCertSecrets(ctx, client, minInst.Namespace, params.Body.CustomCertificates.MinioClientCertificates, externalClientCertSecretName, minInst.Name) + if err != nil { + return err + } + newExternalClientCertSecrets = append(newExternalClientCertSecrets, externalClientCertSecrets...) // Create new CAs Certificate Secrets for MinIO var caCertificates []tenantSecret - for i, caCertificate := range params.Body.CustomCertificates.MinioCAs { + for i, caCertificate := range params.Body.CustomCertificates.MinioCAsCertificates { certificateContent, err := base64.StdEncoding.DecodeString(caCertificate) if err != nil { return err @@ -1091,7 +1098,7 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c if err != nil { return err } - newMinIOExternalCaCertSecret = append(newMinIOExternalCaCertSecret, certificateSecrets...) + newExternalCaCertSecret = append(newExternalCaCertSecret, certificateSecrets...) } // set Security Context @@ -1105,20 +1112,13 @@ func updateTenantSecurity(ctx context.Context, operatorClient OperatorClientI, c } // Update External Certificates - minInst.Spec.ExternalCertSecret = newMinIOExternalCertSecret - minInst.Spec.ExternalCaCertSecret = newMinIOExternalCaCertSecret + minInst.Spec.ExternalCertSecret = newExternalCertSecret + minInst.Spec.ExternalClientCertSecrets = newExternalClientCertSecrets + minInst.Spec.ExternalCaCertSecret = newExternalCaCertSecret _, err = operatorClient.TenantUpdate(ctx, minInst, metav1.UpdateOptions{}) if err != nil { return err } - - // restart all MinIO pods at the same time - err = client.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", miniov2.TenantLabel, minInst.Name), - }) - if err != nil { - return err - } return nil } diff --git a/operatorapi/tenants_helper.go b/operatorapi/tenants_helper.go index eef8496af..cc6957c8f 100644 --- a/operatorapi/tenants_helper.go +++ b/operatorapi/tenants_helper.go @@ -99,20 +99,12 @@ func tenantUpdateCertificates(ctx context.Context, operatorClient OperatorClient if err != nil { return err } - secretName := fmt.Sprintf("%s-secret", tenantName) body := params.Body // check if MinIO is deployed with external certs and user provided new MinIO keypair - if tenant.ExternalCert() && body.Minio != nil { - minioCertSecretName := fmt.Sprintf("%s-instance-external-certificates", secretName) + if tenant.ExternalCert() && body.MinioServerCertificates != nil { + minioCertSecretName := fmt.Sprintf("%s-instance-external-certificates", tenantName) // update certificates - if _, err := createOrReplaceExternalCertSecrets(ctx, clientSet, namespace, body.Minio, minioCertSecretName, tenantName); err != nil { - return err - } - // restart MinIO pods - err := clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", miniov2.TenantLabel, tenantName), - }) - if err != nil { + if _, err := createOrReplaceExternalCertSecrets(ctx, clientSet, namespace, body.MinioServerCertificates, minioCertSecretName, tenantName); err != nil { return err } } diff --git a/operatorapi/tenants_helper_test.go b/operatorapi/tenants_helper_test.go index 6cc5cefec..1c90d426f 100644 --- a/operatorapi/tenants_helper_test.go +++ b/operatorapi/tenants_helper_test.go @@ -99,7 +99,7 @@ func Test_tenantUpdateCertificates(t *testing.T) { namespace: "", params: operator_api.TenantUpdateCertificateParams{ Body: &models.TLSConfiguration{ - Minio: []*models.KeyPairConfiguration{ + MinioServerCertificates: []*models.KeyPairConfiguration{ { Crt: nil, Key: nil, @@ -133,7 +133,7 @@ func Test_tenantUpdateCertificates(t *testing.T) { namespace: "", params: operator_api.TenantUpdateCertificateParams{ Body: &models.TLSConfiguration{ - Minio: []*models.KeyPairConfiguration{ + MinioServerCertificates: []*models.KeyPairConfiguration{ { Crt: &badCrt, Key: &badKey, @@ -167,7 +167,7 @@ func Test_tenantUpdateCertificates(t *testing.T) { namespace: "", params: operator_api.TenantUpdateCertificateParams{ Body: &models.TLSConfiguration{ - Minio: []*models.KeyPairConfiguration{ + MinioServerCertificates: []*models.KeyPairConfiguration{ { Crt: &crt, Key: &key, @@ -195,46 +195,6 @@ func Test_tenantUpdateCertificates(t *testing.T) { }, wantErr: true, }, - { - name: "certificates replaced but error during deleting existing tenant pods", - args: args{ - ctx: context.Background(), - opClient: opClient, - clientSet: k8sClient, - namespace: "", - params: operator_api.TenantUpdateCertificateParams{ - Body: &models.TLSConfiguration{ - Minio: []*models.KeyPairConfiguration{ - { - Crt: &crt, - Key: &key, - }, - }, - }, - }, - mockTenantGet: func(ctx context.Context, namespace string, tenantName string, options metav1.GetOptions) (*miniov2.Tenant, error) { - return &miniov2.Tenant{ - Spec: miniov2.TenantSpec{ - ExternalCertSecret: []*miniov2.LocalCertificateReference{ - { - Name: "secret", - }, - }, - }, - }, nil - }, - mockDeleteSecret: func(ctx context.Context, namespace string, name string, opts metav1.DeleteOptions) error { - return nil - }, - mockCreateSecret: func(ctx context.Context, namespace string, secret *v1.Secret, opts metav1.CreateOptions) (*v1.Secret, error) { - return &v1.Secret{}, nil - }, - mockDeletePodCollection: func(ctx context.Context, namespace string, opts metav1.DeleteOptions, listOpts metav1.ListOptions) error { - return errors.New("error deleting minio pods") - }, - }, - wantErr: true, - }, } for _, tt := range tests { opClientTenantGetMock = tt.args.mockTenantGet diff --git a/operatorapi/tenants_test.go b/operatorapi/tenants_test.go index b36ab4ee9..8befb2ee4 100644 --- a/operatorapi/tenants_test.go +++ b/operatorapi/tenants_test.go @@ -28,6 +28,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" + xhttp "github.com/minio/console/pkg/http" "github.com/minio/console/operatorapi/operations/operator_api" @@ -41,7 +43,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" - types "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/types" "k8s.io/client-go/kubernetes/fake" ) @@ -1215,3 +1217,140 @@ func Test_UpdateDomainsResponse(t *testing.T) { }) } } + +func Test_parseTenantCertificates(t *testing.T) { + ctx, cancel := context.WithCancel(context.Background()) + defer cancel() + kClient := k8sClientMock{} + type args struct { + ctx context.Context + clientSet K8sClientI + namespace string + secrets []*miniov2.LocalCertificateReference + } + tests := []struct { + name string + args args + want []*models.CertificateInfo + mockGetSecret func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) + wantErr bool + }{ + { + name: "empty secrets list", + args: args{ + ctx: ctx, + clientSet: kClient, + secrets: nil, + }, + mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) { + return nil, nil + }, + want: nil, + wantErr: false, + }, + { + name: "error getting secret", + args: args{ + ctx: ctx, + clientSet: kClient, + secrets: []*miniov2.LocalCertificateReference{ + { + Name: "certificate-1", + }, + }, + }, + mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) { + return nil, errors.New("error getting secret") + }, + want: nil, + wantErr: true, + }, + { + name: "error getting certificate because of missing public key", + args: args{ + ctx: ctx, + clientSet: kClient, + secrets: []*miniov2.LocalCertificateReference{ + { + Name: "certificate-1", + Type: "Opaque", + }, + }, + }, + mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) { + certificateSecret := &corev1.Secret{ + Data: map[string][]byte{ + "eaeaeae": []byte(` +-----BEGIN CERTIFICATE----- +MIIBUDCCAQKgAwIBAgIRALdFZh8hLU348ho9wYzlZbAwBQYDK2VwMBIxEDAOBgNV +BAoTB0FjbWUgQ28wHhcNMjIwODE4MjAxMzUzWhcNMjMwODE4MjAxMzUzWjASMRAw +DgYDVQQKEwdBY21lIENvMCowBQYDK2VwAyEAct5c3dzzbNOTi+C62w7QHoSivEWD +MYAheDXZWHC55tGjbTBrMA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggrBgEF +BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs0At8sTSLCjiM24AZhxFY +a2CswjAUBgNVHREEDTALgglsb2NhbGhvc3QwBQYDK2VwA0EABan+d16CeN8UD+QF +a8HBhPAiOpaZeEF6+EqTlq9VfL3eSVd7CLRI+/KtY7ptwomuTeYzuV73adKdE9N2 +ZrJuAw== +-----END CERTIFICATE----- + `), + }, + Type: "Opaque", + } + return certificateSecret, nil + }, + want: nil, + wantErr: true, + }, + { + name: "return certificate from existing secret", + args: args{ + ctx: ctx, + clientSet: kClient, + secrets: []*miniov2.LocalCertificateReference{ + { + Name: "certificate-1", + Type: "Opaque", + }, + }, + }, + mockGetSecret: func(ctx context.Context, namespace, secretName string, opts metav1.GetOptions) (*corev1.Secret, error) { + certificateSecret := &corev1.Secret{ + Data: map[string][]byte{ + "public.crt": []byte(` +-----BEGIN CERTIFICATE----- +MIIBUDCCAQKgAwIBAgIRALdFZh8hLU348ho9wYzlZbAwBQYDK2VwMBIxEDAOBgNV +BAoTB0FjbWUgQ28wHhcNMjIwODE4MjAxMzUzWhcNMjMwODE4MjAxMzUzWjASMRAw +DgYDVQQKEwdBY21lIENvMCowBQYDK2VwAyEAct5c3dzzbNOTi+C62w7QHoSivEWD +MYAheDXZWHC55tGjbTBrMA4GA1UdDwEB/wQEAwIChDATBgNVHSUEDDAKBggrBgEF +BQcDATAPBgNVHRMBAf8EBTADAQH/MB0GA1UdDgQWBBTs0At8sTSLCjiM24AZhxFY +a2CswjAUBgNVHREEDTALgglsb2NhbGhvc3QwBQYDK2VwA0EABan+d16CeN8UD+QF +a8HBhPAiOpaZeEF6+EqTlq9VfL3eSVd7CLRI+/KtY7ptwomuTeYzuV73adKdE9N2 +ZrJuAw== +-----END CERTIFICATE----- + `), + }, + Type: "Opaque", + } + return certificateSecret, nil + }, + want: []*models.CertificateInfo{ + { + SerialNumber: "243609062983998893460787085129017550256", + Name: "certificate-1", + Expiry: "2023-08-18T20:13:53Z", + Domains: []string{"localhost"}, + }, + }, + wantErr: false, + }, + } + for _, tt := range tests { + k8sclientGetSecretMock = tt.mockGetSecret + t.Run(tt.name, func(t *testing.T) { + got, err := parseTenantCertificates(tt.args.ctx, tt.args.clientSet, tt.args.namespace, tt.args.secrets) + if (err != nil) != tt.wantErr { + t.Errorf("parseTenantCertificates(%v, %v, %v, %v)error = %v, wantErr %v", tt.args.ctx, tt.args.clientSet, tt.args.namespace, tt.args.secrets, err, tt.wantErr) + } + assert.Equalf(t, tt.want, got, "parseTenantCertificates(%v, %v, %v, %v)", tt.args.ctx, tt.args.clientSet, tt.args.namespace, tt.args.secrets) + }) + } +} diff --git a/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Encryption.tsx b/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Encryption.tsx index da8484a0b..359283aee 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Encryption.tsx +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Encryption.tsx @@ -123,8 +123,8 @@ const Encryption = ({ classes }: IEncryptionProps) => { const enableTLS = useSelector( (state: AppState) => state.createTenant.fields.security.enableTLS ); - const minioCertificates = useSelector( - (state: AppState) => state.createTenant.certificates.minioCertificates + const minioServerCertificates = useSelector( + (state: AppState) => state.createTenant.certificates.minioServerCertificates ); const serverCertificate = useSelector( (state: AppState) => state.createTenant.certificates.serverCertificate @@ -146,8 +146,8 @@ const Encryption = ({ classes }: IEncryptionProps) => { if ( enableTLS && (enableAutoCert || - (minioCertificates && - minioCertificates.filter( + (minioServerCertificates && + minioServerCertificates.filter( (item) => item.encoded_key && item.encoded_cert ).length > 0)) ) { diff --git a/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Security.tsx b/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Security.tsx index 5af775e66..3632f3340 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Security.tsx +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Security.tsx @@ -32,14 +32,16 @@ import FormSwitchWrapper from "../../../Common/FormComponents/FormSwitchWrapper/ import FileSelector from "../../../Common/FormComponents/FileSelector/FileSelector"; import AddIcon from "@mui/icons-material/Add"; import RemoveIcon from "../../../../../icons/RemoveIcon"; -import SectionTitle from "../../../Common/SectionTitle"; import { addCaCertificate, + deleteCaCertificate, addFileToCaCertificates, addFileToKeyPair, addKeyPair, - deleteCaCertificate, deleteKeyPair, + addClientKeyPair, + deleteClientKeyPair, + addFileToClientKeyPair, isPageValid, updateAddField, } from "../createTenantSlice"; @@ -130,10 +132,13 @@ const Security = ({ classes }: ISecurityProps) => { (state: AppState) => state.createTenant.fields.security.enableCustomCerts ); const minioCertificates = useSelector( - (state: AppState) => state.createTenant.certificates.minioCertificates + (state: AppState) => state.createTenant.certificates.minioServerCertificates + ); + const minioClientCertificates = useSelector( + (state: AppState) => state.createTenant.certificates.minioClientCertificates ); const caCertificates = useSelector( - (state: AppState) => state.createTenant.certificates.caCertificates + (state: AppState) => state.createTenant.certificates.minioCAsCertificates ); // Common @@ -230,7 +235,7 @@ const Security = ({ classes }: ISecurityProps) => { )} - MinIO Certificates +
MinIO Server Certificates
{minioCertificates.map((keyPair: KeyPair, index) => ( { ))}
- - MinIO CA Certificates +
MinIO Client Certificates
+ {minioClientCertificates.map((keyPair: KeyPair, index) => ( + + + { + dispatch( + addFileToClientKeyPair({ + id: keyPair.id, + key: "cert", + fileName: fileName, + value: encodedValue, + }) + ); + }} + accept=".cer,.crt,.cert,.pem" + id="tlsCert" + name="tlsCert" + label="Cert" + value={keyPair.cert} + /> + { + dispatch( + addFileToClientKeyPair({ + id: keyPair.id, + key: "key", + fileName: fileName, + value: encodedValue, + }) + ); + }} + accept=".key,.pem" + id="tlsKey" + name="tlsKey" + label="Key" + value={keyPair.key} + /> + + +
+ { + dispatch(addClientKeyPair()); + }} + disabled={ + index !== minioClientCertificates.length - 1 + } + > + + +
+
+ { + dispatch(deleteClientKeyPair(keyPair.id)); + }} + disabled={minioClientCertificates.length <= 1} + > + + +
+
+
+ ))} +
+ +
MinIO CA Certificates
{caCertificates.map((keyPair: KeyPair, index) => ( { const minioCerts = [ - ...state.certificates.minioCertificates, + ...state.certificates.minioServerCertificates, { id: Date.now().toString(), key: "", @@ -544,10 +553,10 @@ export const createTenantSlice = createSlice({ encoded_cert: "", }, ]; - state.certificates.minioCertificates = [...minioCerts]; + state.certificates.minioServerCertificates = [...minioCerts]; }, addFileToKeyPair: (state, action: PayloadAction) => { - const minioCertificates = state.certificates.minioCertificates; + const minioCertificates = state.certificates.minioServerCertificates; const NCertList = minioCertificates.map((item: KeyPair) => { if (item.id === action.payload.id) { @@ -559,19 +568,58 @@ export const createTenantSlice = createSlice({ } return item; }); - state.certificates.minioCertificates = [...NCertList]; + state.certificates.minioServerCertificates = [...NCertList]; }, deleteKeyPair: (state, action: PayloadAction) => { - const minioCertsList = state.certificates.minioCertificates; + const minioCertsList = state.certificates.minioServerCertificates; if (minioCertsList.length > 1) { - state.certificates.minioCertificates = minioCertsList.filter( + state.certificates.minioServerCertificates = minioCertsList.filter( (item: KeyPair) => item.id !== action.payload ); } }, + addClientKeyPair: (state) => { + const minioClientCerts = [ + ...state.certificates.minioClientCertificates, + { + id: Date.now().toString(), + key: "", + cert: "", + encoded_key: "", + encoded_cert: "", + }, + ]; + state.certificates.minioClientCertificates = [...minioClientCerts]; + }, + addFileToClientKeyPair: (state, action: PayloadAction) => { + const minioClientCertificates = + state.certificates.minioClientCertificates; + + const NCertList = minioClientCertificates.map((item: KeyPair) => { + if (item.id === action.payload.id) { + return { + ...item, + [action.payload.key]: action.payload.fileName, + [`encoded_${action.payload.key}`]: action.payload.value, + }; + } + return item; + }); + state.certificates.minioClientCertificates = [...NCertList]; + }, + deleteClientKeyPair: (state, action: PayloadAction) => { + const minioClientCertsList = state.certificates.minioClientCertificates; + + if (minioClientCertsList.length > 1) { + state.certificates.minioClientCertificates = + minioClientCertsList.filter( + (item: KeyPair) => item.id !== action.payload + ); + } + }, addCaCertificate: (state) => { - state.certificates.caCertificates.push({ + state.certificates.minioCAsCertificates.push({ id: Date.now().toString(), key: "", cert: "", @@ -583,7 +631,7 @@ export const createTenantSlice = createSlice({ state, action: PayloadAction ) => { - const caCertificates = state.certificates.caCertificates; + const caCertificates = state.certificates.minioCAsCertificates; const NACList = caCertificates.map((item: KeyPair) => { if (item.id === action.payload.id) { @@ -595,15 +643,14 @@ export const createTenantSlice = createSlice({ } return item; }); - state.certificates.caCertificates = NACList; + state.certificates.minioCAsCertificates = NACList; }, deleteCaCertificate: (state, action: PayloadAction) => { - const CACertsList = state.certificates.caCertificates; + const CACertsList = state.certificates.minioCAsCertificates; if (CACertsList.length > 1) { - const cleanCaCertsList = CACertsList.filter( + state.certificates.minioCAsCertificates = CACertsList.filter( (item: KeyPair) => item.id !== action.payload ); - state.certificates.caCertificates = cleanCaCertsList; } }, addConsoleCertificate: (state, action: PayloadAction) => { @@ -991,6 +1038,9 @@ export const { addKeyPair, deleteKeyPair, addFileToKeyPair, + addClientKeyPair, + deleteClientKeyPair, + addFileToClientKeyPair, addConsoleCertificate, addFileServerCert, addFileClientCert, diff --git a/portal-ui/src/screens/Console/Tenants/AddTenant/thunks/createTenantThunk.ts b/portal-ui/src/screens/Console/Tenants/AddTenant/thunks/createTenantThunk.ts index 2985b551d..3c96c50a2 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/thunks/createTenantThunk.ts +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/thunks/createTenantThunk.ts @@ -62,10 +62,9 @@ export const createTenantAsync = createAsyncThunk( const ADServerStartTLS = fields.identityProvider.ADServerStartTLS; const accessKeys = fields.identityProvider.accessKeys; const secretKeys = fields.identityProvider.secretKeys; - const minioCertificates = certificates.minioCertificates; - const caCertificates = certificates.caCertificates; - const consoleCaCertificates = certificates.consoleCaCertificates; - const consoleCertificate = certificates.consoleCertificate; + const minioServerCertificates = certificates.minioServerCertificates; + const minioClientCertificates = certificates.minioClientCertificates; + const minioCAsCertificates = certificates.minioCAsCertificates; const serverCertificate = certificates.serverCertificate; const clientCertificate = certificates.clientCertificate; const vaultCertificate = certificates.vaultCertificate; @@ -290,30 +289,13 @@ export const createTenantAsync = createAsyncThunk( }; } - let tenantCerts: any = null; - let consoleCerts: any = null; - let caCerts: any = null; - let consoleCaCerts: any = null; + let tenantServerCertificates: any = null; + let tenantClientCertificates: any = null; + let tenantCAsCertificates: any = null; - if (caCertificates.length > 0) { - caCerts = { - ca_certificates: caCertificates - .map((keyPair: KeyPair) => keyPair.encoded_cert) - .filter((keyPair) => keyPair), - }; - } - - if (consoleCaCertificates.length > 0) { - consoleCaCerts = { - console_ca_certificates: consoleCaCertificates - .map((keyPair: KeyPair) => keyPair.encoded_cert) - .filter((keyPair) => keyPair), - }; - } - - if (enableTLS && minioCertificates.length > 0) { - tenantCerts = { - minio: minioCertificates + if (enableTLS && minioServerCertificates.length > 0) { + tenantServerCertificates = { + minioServerCertificates: minioServerCertificates .map((keyPair: KeyPair) => ({ crt: keyPair.encoded_cert, key: keyPair.encoded_key, @@ -322,27 +304,36 @@ export const createTenantAsync = createAsyncThunk( }; } - if ( - enableTLS && - consoleCertificate.encoded_cert !== "" && - consoleCertificate.encoded_key !== "" - ) { - consoleCerts = { - console: { - crt: consoleCertificate.encoded_cert, - key: consoleCertificate.encoded_key, - }, + if (enableTLS && minioClientCertificates.length > 0) { + tenantClientCertificates = { + minioClientCertificates: minioClientCertificates + .map((keyPair: KeyPair) => ({ + crt: keyPair.encoded_cert, + key: keyPair.encoded_key, + })) + .filter((keyPair) => keyPair.crt && keyPair.key), }; } - if (tenantCerts || consoleCerts || caCerts || consoleCaCerts) { + if (enableTLS && minioCAsCertificates.length > 0) { + tenantCAsCertificates = { + minioCAsCertificates: minioCAsCertificates + .map((keyPair: KeyPair) => keyPair.encoded_cert) + .filter((keyPair) => keyPair), + }; + } + + if ( + minioServerCertificates || + minioClientCertificates || + minioCAsCertificates + ) { dataSend = { ...dataSend, tls: { - ...tenantCerts, - ...consoleCerts, - ...caCerts, - ...consoleCaCerts, + ...tenantServerCertificates, + ...tenantClientCertificates, + ...tenantCAsCertificates, }, }; } diff --git a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantSecurity.tsx b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantSecurity.tsx index ba7509953..df1ed0ad1 100644 --- a/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantSecurity.tsx +++ b/portal-ui/src/screens/Console/Tenants/TenantDetails/TenantSecurity.tsx @@ -47,7 +47,6 @@ import api from "../../../../common/api"; import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog"; import Loader from "../../Common/Loader/Loader"; import TLSCertificate from "../../Common/TLSCertificate/TLSCertificate"; -import SectionTitle from "../../Common/SectionTitle"; import SecurityContextSelector from "../securityContextSelector"; import { setRunAsUser, @@ -155,7 +154,20 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { string[] >([]); // MinIO certificates - const [minioCertificates, setMinioCertificates] = useState([ + const [minioServerCertificates, setMinioServerCertificates] = useState< + KeyPair[] + >([ + { + id: Date.now().toString(), + key: "", + cert: "", + encoded_key: "", + encoded_cert: "", + }, + ]); + const [minioClientCertificates, setMinioClientCertificates] = useState< + KeyPair[] + >([ { id: Date.now().toString(), key: "", @@ -173,9 +185,10 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { encoded_cert: "", }, ]); - const [minioTLSCertificateSecrets, setMinioTLSCertificateSecrets] = useState< - ICertificateInfo[] - >([]); + const [minioServerCertificateSecrets, setMinioServerCertificateSecrets] = + useState([]); + const [minioClientCertificateSecrets, setMinioClientCertificateSecrets] = + useState([]); const [minioTLSCaCertificateSecrets, setMinioTLSCaCertificateSecrets] = useState([]); @@ -204,11 +217,16 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { .then((res: ITenantSecurityResponse) => { setEnableAutoCert(res.autoCert); setEnableTLS(res.autoCert); - if (res.customCertificates.minio || res.customCertificates.minioCAs) { + if ( + res.customCertificates.minio || + res.customCertificates.client || + res.customCertificates.minioCAs + ) { setEnableCustomCerts(true); setEnableTLS(true); } - setMinioTLSCertificateSecrets(res.customCertificates.minio || []); + setMinioServerCertificateSecrets(res.customCertificates.minio || []); + setMinioClientCertificateSecrets(res.customCertificates.client || []); setMinioTLSCaCertificateSecrets(res.customCertificates.minioCAs || []); dispatch(setRunAsGroup(res.securityContext.runAsGroup)); dispatch(setRunAsUser(res.securityContext.runAsUser)); @@ -245,24 +263,32 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { if (enableCustomCerts) { payload["customCertificates"] = { secretsToBeDeleted: certificatesToBeRemoved, - minio: minioCertificates + minioServerCertificates: minioServerCertificates .map((keyPair: KeyPair) => ({ crt: keyPair.encoded_cert, key: keyPair.encoded_key, })) .filter((cert: any) => cert.crt && cert.key), - minioCAs: minioCaCertificates + minioClientCertificates: minioClientCertificates + .map((keyPair: KeyPair) => ({ + crt: keyPair.encoded_cert, + key: keyPair.encoded_key, + })) + .filter((cert: any) => cert.crt && cert.key), + minioCAsCertificates: minioCaCertificates .map((keyPair: KeyPair) => keyPair.encoded_cert) .filter((cert: any) => cert), }; } else { payload["customCertificates"] = { secretsToBeDeleted: [ - ...minioTLSCertificateSecrets.map((cert) => cert.name), + ...minioServerCertificateSecrets.map((cert) => cert.name), + ...minioClientCertificateSecrets.map((cert) => cert.name), ...minioTLSCaCertificateSecrets.map((cert) => cert.name), ], - minio: [], - minioCAs: [], + minioServerCertificates: [], + minioClientCertificates: [], + minioCAsCertificates: [], }; } api @@ -276,7 +302,16 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { // Close confirmation modal setDialogOpen(false); // Refresh Information and reset forms - setMinioCertificates([ + setMinioServerCertificates([ + { + cert: "", + encoded_cert: "", + encoded_key: "", + id: Date.now().toString(), + key: "", + }, + ]); + setMinioClientCertificates([ { cert: "", encoded_cert: "", @@ -311,15 +346,22 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { certificateInfo.name, ]); - // Update MinIO TLS certificate secrets - const updatedMinIOTLSCertificateSecrets = minioTLSCertificateSecrets.filter( - (certificateSecret) => certificateSecret.name !== certificateInfo.name - ); + // Update MinIO server TLS certificate secrets + const updatedMinioServerCertificateSecrets = + minioServerCertificateSecrets.filter( + (certificateSecret) => certificateSecret.name !== certificateInfo.name + ); + // Update MinIO client TLS certificate secrets + const updatedMinioClientCertificateSecrets = + minioClientCertificateSecrets.filter( + (certificateSecret) => certificateSecret.name !== certificateInfo.name + ); const updatedMinIOTLSCaCertificateSecrets = minioTLSCaCertificateSecrets.filter( (certificateSecret) => certificateSecret.name !== certificateInfo.name ); - setMinioTLSCertificateSecrets(updatedMinIOTLSCertificateSecrets); + setMinioServerCertificateSecrets(updatedMinioServerCertificateSecrets); + setMinioClientCertificateSecrets(updatedMinioClientCertificateSecrets); setMinioTLSCaCertificateSecrets(updatedMinIOTLSCaCertificateSecrets); }; @@ -330,13 +372,18 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { fileName: string, value: string ) => { - let certificates = minioCertificates; + let certificates = minioServerCertificates; let updateCertificates: any = () => {}; switch (type) { case "minio": { - certificates = minioCertificates; - updateCertificates = setMinioCertificates; + certificates = minioServerCertificates; + updateCertificates = setMinioServerCertificates; + break; + } + case "client": { + certificates = minioClientCertificates; + updateCertificates = setMinioClientCertificates; break; } case "minioCAs": { @@ -361,13 +408,18 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { }; const deleteKeyPair = (type: string, id: string) => { - let certificates = minioCertificates; + let certificates = minioServerCertificates; let updateCertificates: any = () => {}; switch (type) { case "minio": { - certificates = minioCertificates; - updateCertificates = setMinioCertificates; + certificates = minioServerCertificates; + updateCertificates = setMinioServerCertificates; + break; + } + case "client": { + certificates = minioClientCertificates; + updateCertificates = setMinioClientCertificates; break; } case "minioCAs": { @@ -387,13 +439,18 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { }; const addKeyPair = (type: string) => { - let certificates = minioCertificates; + let certificates = minioServerCertificates; let updateCertificates: any = () => {}; switch (type) { case "minio": { - certificates = minioCertificates; - updateCertificates = setMinioCertificates; + certificates = minioServerCertificates; + updateCertificates = setMinioServerCertificates; + break; + } + case "client": { + certificates = minioClientCertificates; + updateCertificates = setMinioClientCertificates; break; } case "minioCAs": { @@ -415,6 +472,7 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { ]; updateCertificates(updatedCertificates); }; + return ( { {enableCustomCerts && ( - MinIO Certificates +
MinIO Server Certificates
- {minioTLSCertificateSecrets.map( + {minioServerCertificateSecrets.map( (certificateInfo: ICertificateInfo) => ( { ) )} - - {minioCertificates.map((keyPair, index) => ( + {minioServerCertificates.map((keyPair, index) => ( { size={"small"} onClick={() => addKeyPair("minio")} disabled={ - index !== minioCertificates.length - 1 + index !== minioServerCertificates.length - 1 } > @@ -571,7 +628,7 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { onClick={() => deleteKeyPair("minio", keyPair.id) } - disabled={minioCertificates.length <= 1} + disabled={minioServerCertificates.length <= 1} > @@ -580,8 +637,92 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { ))} + + +
MinIO Client Certificates
+
- MinIO CA Certificates + {minioClientCertificateSecrets.map( + (certificateInfo: ICertificateInfo) => ( + removeCertificate(certificateInfo)} + /> + ) + )} + + + {minioClientCertificates.map((keyPair, index) => ( + + + + addFileToKeyPair( + "client", + keyPair.id, + "cert", + fileName, + encodedValue + ) + } + accept=".cer,.crt,.cert,.pem" + id="tlsCert" + name="tlsCert" + label="Cert" + value={keyPair.cert} + /> + + addFileToKeyPair( + "client", + keyPair.id, + "key", + fileName, + encodedValue + ) + } + accept=".key,.pem" + id="tlsKey" + name="tlsKey" + label="Key" + value={keyPair.key} + /> + + +
+ addKeyPair("client")} + disabled={ + index !== minioClientCertificates.length - 1 + } + > + + +
+
+ + deleteKeyPair("client", keyPair.id) + } + disabled={minioClientCertificates.length <= 1} + > + + +
+
+
+ ))} +
+ + +
MinIO CA Certificates
{minioTLSCaCertificateSecrets.map( @@ -593,7 +734,6 @@ const TenantSecurity = ({ classes }: ITenantSecurity) => { ) )} - {minioCaCertificates.map((keyPair: KeyPair, index) => (