diff --git a/go.mod b/go.mod index e841d10a5..0e81f972d 100644 --- a/go.mod +++ b/go.mod @@ -18,8 +18,8 @@ require ( github.com/minio/kes v0.11.0 github.com/minio/mc v0.0.0-20200725183142-90d22b271f60 github.com/minio/minio v0.0.0-20200725154241-abbf6ce6ccf8 - github.com/minio/minio-go/v7 v7.0.2-0.20200722162308-e0105ca08252 - github.com/minio/operator v0.0.0-20200730044813-c2895a5065a1 + github.com/minio/minio-go/v7 v7.0.2 + github.com/minio/operator v0.0.0-20200806194125-c2ff646f4af1 github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35 // indirect github.com/stretchr/testify v1.6.1 github.com/unrolled/secure v1.0.7 @@ -27,7 +27,7 @@ require ( golang.org/x/net v0.0.0-20200707034311-ab3426394381 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45 gopkg.in/yaml.v2 v2.3.0 - k8s.io/api v0.18.0 - k8s.io/apimachinery v0.18.0 - k8s.io/client-go v0.18.0 + k8s.io/api v0.18.6 + k8s.io/apimachinery v0.18.6 + k8s.io/client-go v0.18.6 ) diff --git a/go.sum b/go.sum index b337d8581..25487ed84 100644 --- a/go.sum +++ b/go.sum @@ -270,6 +270,8 @@ github.com/golang/protobuf v1.4.0-rc.2/go.mod h1:LlEzMj4AhA7rCAGe4KMBDvJI+AwstrU github.com/golang/protobuf v1.4.0-rc.4.0.20200313231945-b860323f09d0/go.mod h1:WU3c8KckQ9AFe+yFwt9sWVRKCVIyN9cPHBJSNnbL67w= github.com/golang/protobuf v1.4.0 h1:oOuy+ugB+P/kBdUnG5QaMXSIyJ1q38wWSojYCb3z5VQ= github.com/golang/protobuf v1.4.0/go.mod h1:jodUvKwWbYaEsadDk5Fwe5c77LiNKVO9IDvqG2KuDX0= +github.com/golang/protobuf v1.4.2 h1:+Z5KGCizgyZCbGh1KZqA0fcLLkwbsjIzS4aV2v7wJX0= +github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4= github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/gomodule/redigo v2.0.0+incompatible h1:K/R+8tc58AaqLkqG2Ol3Qk+DR/TlNuhuh457pBFPtt0= @@ -284,6 +286,8 @@ github.com/google/go-cmp v0.3.1 h1:Xye71clBPdm5HgqGwUkwhbynsUJZhDbS20FvLhQ2izg= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0 h1:xsAVV57WRhGj6kEIi8ReJzQlHHqcBYCElAvkovg3B/4= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.4.1 h1:/exdXoGamhu5ONeUJH0deniYLWYvQwW66yvlfiiKTu0= +github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= github.com/google/gofuzz v1.1.0 h1:Hsa8mG0dQ46ij8Sl2AYJDUv1oA9/d6Vk+3LG99Oe02g= github.com/google/gofuzz v1.1.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= @@ -348,6 +352,8 @@ github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09 github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.1 h1:0hERBMJE1eitiLkihrMvRVBYAkpHzc/J3QdDN+dAcgU= github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= +github.com/hashicorp/golang-lru v0.5.4 h1:YDjusn29QI/Das2iO9M0BHnIbxPeyuCHsjMW+lJfyTc= +github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hashicorp/raft v1.1.2 h1:oxEL5DDeurYxLd3UbcY/hccgSPhLLpiBZ1YxtWEq59c= @@ -363,6 +369,8 @@ github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= github.com/imdario/mergo v0.3.5 h1:JboBksRwiiAJWvIYJVo46AfV+IAIKZpfrSzVKj42R4Q= github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA= +github.com/imdario/mergo v0.3.10 h1:6q5mVkdH/vYmqngx7kZQTjJ5HRsx+ImorDIEQ+beJgc= +github.com/imdario/mergo v0.3.10/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA= github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf h1:WfD7VjIE6z8dIvMsI4/s+1qr5EL+zoIGev1BQj1eoJ8= github.com/inconshreveable/go-update v0.0.0-20160112193335-8152e7eb6ccf/go.mod h1:hyb9oH7vZsitZCiBt0ZvifOrB+qc8PS5IiilCIb87rg= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= @@ -469,8 +477,12 @@ github.com/minio/minio v0.0.0-20200725154241-abbf6ce6ccf8/go.mod h1:NBWtYp4t5pt3 github.com/minio/minio-go/v7 v7.0.1/go.mod h1:dJ80Mv2HeGkYLH1sqS/ksz07ON6csH3S6JUMSQ2zAns= github.com/minio/minio-go/v7 v7.0.2-0.20200722162308-e0105ca08252 h1:V2JkMDoSmEIhRcMJwX3qeJVOzy1B5bHpHbZaQu77vbs= github.com/minio/minio-go/v7 v7.0.2-0.20200722162308-e0105ca08252/go.mod h1:dJ80Mv2HeGkYLH1sqS/ksz07ON6csH3S6JUMSQ2zAns= +github.com/minio/minio-go/v7 v7.0.2 h1:P/7wFd4KrRBHVo7AKdcqO+9ReoS+XpMjfRFoE5quH0E= +github.com/minio/minio-go/v7 v7.0.2/go.mod h1:dJ80Mv2HeGkYLH1sqS/ksz07ON6csH3S6JUMSQ2zAns= github.com/minio/operator v0.0.0-20200730044813-c2895a5065a1 h1:cTgvRgFBUVxbnxhQUioT2T7SH0M7AyvO7dDX32yKPGw= github.com/minio/operator v0.0.0-20200730044813-c2895a5065a1/go.mod h1:RLhFkLcL65qmrgUQJHrRwb1Lb4yHgD/DfjNENY2WNXg= +github.com/minio/operator v0.0.0-20200806194125-c2ff646f4af1 h1:ijXSIPjn/GZx1+RW1HQpScoifLNr8lVw5LNVKxysMWg= +github.com/minio/operator v0.0.0-20200806194125-c2ff646f4af1/go.mod h1:V8RL9xPw3C9rC7DuEy7JHeSiOlTWvQhZvh2+YySBFbk= github.com/minio/selfupdate v0.3.0 h1:1qfaZscU3hWwX1cF5m5Dov8Z5aZNvPHk9LROzIkas1k= github.com/minio/selfupdate v0.3.0/go.mod h1:b8ThJzzH7u2MkF6PcIra7KaXO9Khf6alWPvMSyTDCFM= github.com/minio/sha256-simd v0.1.1 h1:5QHSlgo3nt5yKOJrC7W8w7X+NFl8cMPZm96iu8kKUJU= @@ -594,8 +606,12 @@ github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkB github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/secure-io/sio-go v0.3.0 h1:QKGb6rGJeiExac9wSWxnWPYo8O8OFN7lxXQvHshX6vo= github.com/secure-io/sio-go v0.3.0/go.mod h1:D3KmXgKETffyYxBdFRN+Hpd2WzhzqS0EQwT3XWsAcBU= +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 v2.20.3-0.20200314133625-53cec6b37e6a+incompatible h1:YiKUe2ZOmfpDBH4OSyxwkx/mjNqHHnNhOtZ2mPyRme8= github.com/shirou/gopsutil v2.20.3-0.20200314133625-53cec6b37e6a+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= +github.com/shirou/gopsutil v2.20.6+incompatible h1:P37G9YH8M4vqkKcwBosp+URN5O8Tay67D2MbR361ioY= +github.com/shirou/gopsutil v2.20.6+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= @@ -700,6 +716,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20191117063200-497ca9f6d64f/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975 h1:/Tl7pH94bvbAAHBdZJT947M/+gp0+CqQXDtMRC0fseo= golang.org/x/crypto v0.0.0-20200220183623-bac4c82f6975/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200323165209-0ec3e9974c59/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200709230013-948cd5f35899 h1:DZhuSZLsGlFL4CmhA8BcRA0mnthyA/nZ00AqCUo7vHg= @@ -779,6 +796,7 @@ golang.org/x/sys v0.0.0-20191022100944-742c48ecaeb7/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd h1:xhmwyvizuTgC2qz7ZlMluP20uW+C3Rm0FD/WLDX8884= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae h1:Ih9Yo4hSPImZOpfGuA4bR/ORKTAbhZo2AbWNRCnevdo= @@ -851,6 +869,8 @@ google.golang.org/protobuf v1.20.1-0.20200309200217-e05f789c0967/go.mod h1:A+miE google.golang.org/protobuf v1.21.0/go.mod h1:47Nbq4nVaFHyn7ilMalzfO3qCViNmqZ2kzikPIcrTAo= google.golang.org/protobuf v1.22.0 h1:cJv5/xdbk1NnMPR1VP9+HU6gupuG9MLBoH1r6RHZ2MY= google.golang.org/protobuf v1.22.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= +google.golang.org/protobuf v1.23.0 h1:4MY060fB1DLGMB/7MBTLnwQUY6+F09GEiz6SsrNqyzM= +google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d h1:TxyelI5cVkbREznMhfzycHdkp5cLA7DpE+GKjSslYhM= gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUyUwEgHQXw849cJrilpS5NeIjOWESAw= @@ -911,10 +931,16 @@ honnef.co/go/tools v0.0.1-2019.2.3 h1:3JgtbtFHMiCmsznwGVTUWbgGov+pVqnlf1dEJTNAXe honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= k8s.io/api v0.18.0 h1:lwYk8Vt7rsVTwjRU6pzEsa9YNhThbmbocQlKvNBB4EQ= k8s.io/api v0.18.0/go.mod h1:q2HRQkfDzHMBZL9l/y9rH63PkQl4vae0xRT+8prbrK8= +k8s.io/api v0.18.6 h1:osqrAXbOQjkKIWDTjrqxWQ3w0GkKb1KA1XkUGHHYpeE= +k8s.io/api v0.18.6/go.mod h1:eeyxr+cwCjMdLAmr2W3RyDI0VvTawSg/3RFFBEnmZGI= k8s.io/apimachinery v0.18.0 h1:fuPfYpk3cs1Okp/515pAf0dNhL66+8zk8RLbSX+EgAE= k8s.io/apimachinery v0.18.0/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA= +k8s.io/apimachinery v0.18.6 h1:RtFHnfGNfd1N0LeSrKCUznz5xtUP1elRGvHJbL3Ntag= +k8s.io/apimachinery v0.18.6/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko= k8s.io/client-go v0.18.0 h1:yqKw4cTUQraZK3fcVCMeSa+lqKwcjZ5wtcOIPnxQno4= k8s.io/client-go v0.18.0/go.mod h1:uQSYDYs4WhVZ9i6AIoEZuwUggLVEF64HOD37boKAtF8= +k8s.io/client-go v0.18.6 h1:I+oWqJbibLSGsZj8Xs8F0aWVXJVIoUHWaaJV3kUN/Zw= +k8s.io/client-go v0.18.6/go.mod h1:/fwtGLjYMS1MaM5oi+eXhKwG+1UHidUEXRh6cNsdO0Q= k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= k8s.io/klog v0.0.0-20181102134211-b9b56d5dfc92/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= k8s.io/klog v0.3.0/go.mod h1:Gq+BEi5rUBO/HRz0bTSXDUcqjScdoY3a9IHpCEIOOfk= diff --git a/models/encryption_configuration.go b/models/encryption_configuration.go index bf3216f7f..bd88010f2 100644 --- a/models/encryption_configuration.go +++ b/models/encryption_configuration.go @@ -46,9 +46,6 @@ type EncryptionConfiguration struct { // image Image string `json:"image,omitempty"` - // master key - MasterKey string `json:"master_key,omitempty"` - // server Server *EncryptionConfigurationServer `json:"server,omitempty"` diff --git a/models/vault_configuration.go b/models/vault_configuration.go index 65b2b723d..d9e7652c3 100644 --- a/models/vault_configuration.go +++ b/models/vault_configuration.go @@ -53,6 +53,9 @@ type VaultConfiguration struct { // status Status *VaultConfigurationStatus `json:"status,omitempty"` + + // tls + TLS *VaultConfigurationTLS `json:"tls,omitempty"` } // Validate validates this vault configuration @@ -71,6 +74,10 @@ func (m *VaultConfiguration) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateTLS(formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { return errors.CompositeValidationError(res...) } @@ -122,6 +129,24 @@ func (m *VaultConfiguration) validateStatus(formats strfmt.Registry) error { return nil } +func (m *VaultConfiguration) validateTLS(formats strfmt.Registry) error { + + if swag.IsZero(m.TLS) { // not required + return nil + } + + if m.TLS != nil { + if err := m.TLS.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("tls") + } + return err + } + } + + return nil +} + // MarshalBinary interface implementation func (m *VaultConfiguration) MarshalBinary() ([]byte, error) { if m == nil { @@ -245,3 +270,41 @@ func (m *VaultConfigurationStatus) UnmarshalBinary(b []byte) error { *m = res return nil } + +// VaultConfigurationTLS vault configuration TLS +// +// swagger:model VaultConfigurationTLS +type VaultConfigurationTLS struct { + + // ca + Ca string `json:"ca,omitempty"` + + // crt + Crt string `json:"crt,omitempty"` + + // key + Key string `json:"key,omitempty"` +} + +// Validate validates this vault configuration TLS +func (m *VaultConfigurationTLS) Validate(formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *VaultConfigurationTLS) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *VaultConfigurationTLS) UnmarshalBinary(b []byte) error { + var res VaultConfigurationTLS + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/pkg/kes/kes.go b/pkg/kes/kes.go index ea623cf7a..7a2e194b9 100644 --- a/pkg/kes/kes.go +++ b/pkg/kes/kes.go @@ -9,12 +9,14 @@ import ( "github.com/minio/kes" ) +type Identity = kes.Identity + type TLSProxyHeader struct { ClientCert string `yaml:"cert,omitempty"` } type TLSProxy struct { - Identities *[]kes.Identity `yaml:"identities,omitempty"` + Identities *[]Identity `yaml:"identities,omitempty"` Header *TLSProxyHeader `yaml:"header,omitempty"` } @@ -25,8 +27,8 @@ type TLS struct { } type Policy struct { - Paths []string `yaml:"paths,omitempty"` - Identities []kes.Identity `yaml:"identities,omitempty"` + Paths []string `yaml:"paths,omitempty"` + Identities []Identity `yaml:"identities,omitempty"` } type Expiry struct { @@ -120,7 +122,7 @@ type Keys struct { type ServerConfig struct { Addr string `yaml:"address,omitempty"` - Root kes.Identity `yaml:"root,omitempty"` + Root Identity `yaml:"root,omitempty"` TLS TLS `yaml:"tls,omitempty"` Policies map[string]Policy `yaml:"policy,omitempty"` Cache Cache `yaml:"cache,omitempty"` diff --git a/restapi/admin_tenants.go b/restapi/admin_tenants.go index 05c5bca23..2594b3b68 100644 --- a/restapi/admin_tenants.go +++ b/restapi/admin_tenants.go @@ -33,10 +33,10 @@ import ( "time" "github.com/minio/console/pkg/kes" - kes2 "github.com/minio/kes" "gopkg.in/yaml.v2" "k8s.io/apimachinery/pkg/api/resource" "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes" corev1 "k8s.io/api/core/v1" @@ -522,217 +522,15 @@ func getTenantCreatedResponse(session *models.Principal, params admin_api.Create Name: "MINIO_KMS_AUTO_ENCRYPTION", Value: "on", }) - - if tenantReq.Encryption.MasterKey != "" { - // Configure MinIO to use MINIO_KMS_MASTER_KEY legacy key - // https://docs.min.io/docs/minio-vault-legacy.html - minInst.Spec.Env = append(minInst.Spec.Env, corev1.EnvVar{ - Name: "MINIO_KMS_MASTER_KEY", - Value: tenantReq.Encryption.MasterKey, - }) - } else { - // KES configuration for Tenant instance - minInst.Spec.KES = &operator.KESConfig{ - Image: "minio/kes:latest", - Replicas: 1, - Metadata: nil, - } - // Using custom image for KES - if tenantReq.Encryption.Image != "" { - minInst.Spec.KES.Image = tenantReq.Encryption.Image - } - // Secret to store KES server TLS certificates - // TODO check if AutoCert it's already configured - serverTLSCrt, err := base64.StdEncoding.DecodeString(*tenantReq.Encryption.Server.Crt) - if err != nil { - return nil, err - } - serverTLSKey, err := base64.StdEncoding.DecodeString(*tenantReq.Encryption.Server.Key) - if err != nil { - return nil, err - } - kesExternalCertificateSecretName := fmt.Sprintf("%s-kes-external-certificates", secretName) - kesExternalCertificateSecret := corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: kesExternalCertificateSecretName, - }, - Type: corev1.SecretTypeTLS, - Immutable: &imm, - Data: map[string][]byte{ - "tls.crt": serverTLSCrt, - "tls.key": serverTLSKey, - }, - } - _, err = clientset.CoreV1().Secrets(ns).Create(ctx, &kesExternalCertificateSecret, metav1.CreateOptions{}) - if err != nil { - return nil, err - } - // External certificates used by KES - minInst.Spec.KES.ExternalCertSecret = &operator.LocalCertificateReference{ - Name: kesExternalCertificateSecretName, - Type: "kubernetes.io/tls", - } - - // Secret to store KES clients TLS certificates (mTLS authentication) - clientTLSCrt, err := base64.StdEncoding.DecodeString(*tenantReq.Encryption.Client.Crt) - if err != nil { - return nil, err - } - clientTLSKey, err := base64.StdEncoding.DecodeString(*tenantReq.Encryption.Client.Key) - if err != nil { - return nil, err - } - instanceExternalClientCertificateSecretName := fmt.Sprintf("%s-instance-external-client-certificates", secretName) - instanceExternalClientCertificateSecret := corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: instanceExternalClientCertificateSecretName, - }, - Type: corev1.SecretTypeTLS, - Immutable: &imm, - Data: map[string][]byte{ - "tls.crt": clientTLSCrt, - "tls.key": clientTLSKey, - }, - } - _, err = clientset.CoreV1().Secrets(ns).Create(ctx, &instanceExternalClientCertificateSecret, metav1.CreateOptions{}) - if err != nil { - return nil, err - } - // KES client certificates used by MinIO instance - minInst.Spec.ExternalClientCertSecret = &operator.LocalCertificateReference{ - Name: instanceExternalClientCertificateSecretName, - Type: "kubernetes.io/tls", - } - // Calculate the client cert identity based on the clientTLSCrt - h := crypto.SHA256.New() - certificate, err := kes.ParseCertificate(clientTLSCrt) - if err != nil { - return nil, err - } - h.Write(certificate.RawSubjectPublicKeyInfo) - clientCrtIdentity := hex.EncodeToString(h.Sum(nil)) - // Default configuration for KES - kesConfig := kes.ServerConfig{ - Addr: "0.0.0.0:7373", - Root: "disabled", - TLS: kes.TLS{ - KeyPath: "/tmp/kes/server.key", - CertPath: "/tmp/kes/server.crt", - }, - Policies: map[string]kes.Policy{ - "default-policy": { - Paths: []string{ - "/v1/key/create/my-minio-key", - "/v1/key/generate/my-minio-key", - "/v1/key/decrypt/my-minio-key", - }, - Identities: []kes2.Identity{ - kes2.Identity(clientCrtIdentity), - }, - }, - }, - Cache: kes.Cache{ - Expiry: &kes.Expiry{ - Any: 5 * time.Minute, - Unused: 20 * time.Second, - }, - }, - Log: kes.Log{ - Error: "on", - Audit: "off", - }, - Keys: kes.Keys{}, - } - // if encryption is enabled and encryption is configured to use Vault - if tenantReq.Encryption.Vault != nil { - // Initialize Vault Config - kesConfig.Keys.Vault = &kes.Vault{ - Endpoint: *tenantReq.Encryption.Vault.Endpoint, - EnginePath: tenantReq.Encryption.Vault.Engine, - Namespace: tenantReq.Encryption.Vault.Namespace, - Prefix: tenantReq.Encryption.Vault.Prefix, - Status: &kes.VaultStatus{ - Ping: 10 * time.Second, - }, - } - // Vault AppRole credentials - if tenantReq.Encryption.Vault.Approle != nil { - kesConfig.Keys.Vault.AppRole = &kes.AppRole{ - EnginePath: tenantReq.Encryption.Vault.Approle.Engine, - ID: *tenantReq.Encryption.Vault.Approle.ID, - Secret: *tenantReq.Encryption.Vault.Approle.Secret, - Retry: 15 * time.Second, - } - } else { - return nil, errors.New("approle credentials missing for kes") - } - } else if tenantReq.Encryption.Aws != nil { - // Initialize AWS - kesConfig.Keys.Aws = &kes.Aws{ - SecretsManager: &kes.AwsSecretManager{}, - } - // AWS basic configuration - if tenantReq.Encryption.Aws.Secretsmanager != nil { - kesConfig.Keys.Aws.SecretsManager.Endpoint = *tenantReq.Encryption.Aws.Secretsmanager.Endpoint - kesConfig.Keys.Aws.SecretsManager.Region = *tenantReq.Encryption.Aws.Secretsmanager.Region - kesConfig.Keys.Aws.SecretsManager.KmsKey = tenantReq.Encryption.Aws.Secretsmanager.Kmskey - // AWS credentials - if tenantReq.Encryption.Aws.Secretsmanager.Credentials != nil { - kesConfig.Keys.Aws.SecretsManager.Login = &kes.AwsSecretManagerLogin{ - AccessKey: *tenantReq.Encryption.Aws.Secretsmanager.Credentials.Accesskey, - SecretKey: *tenantReq.Encryption.Aws.Secretsmanager.Credentials.Secretkey, - SessionToken: tenantReq.Encryption.Aws.Secretsmanager.Credentials.Token, - } - } - } - } else if tenantReq.Encryption.Gemalto != nil { - // Initialize Gemalto - kesConfig.Keys.Gemalto = &kes.Gemalto{ - KeySecure: &kes.GemaltoKeySecure{}, - } - // Gemalto Configuration - if tenantReq.Encryption.Gemalto.Keysecure != nil { - kesConfig.Keys.Gemalto.KeySecure.Endpoint = *tenantReq.Encryption.Gemalto.Keysecure.Endpoint - // Gemalto TLS configuration - if tenantReq.Encryption.Gemalto.Keysecure.TLS != nil { - kesConfig.Keys.Gemalto.KeySecure.TLS = &kes.GemaltoTLS{ - CAPath: *tenantReq.Encryption.Gemalto.Keysecure.TLS.Ca, - } - } - // Gemalto Login - if tenantReq.Encryption.Gemalto.Keysecure.Credentials != nil { - kesConfig.Keys.Gemalto.KeySecure.Credentials = &kes.GemaltoCredentials{ - Token: *tenantReq.Encryption.Gemalto.Keysecure.Credentials.Token, - Domain: *tenantReq.Encryption.Gemalto.Keysecure.Credentials.Domain, - Retry: 15 * time.Second, - } - } - } - } - // Generate Yaml configuration for KES - serverConfigYaml, err := yaml.Marshal(kesConfig) - if err != nil { - return nil, err - } - // Secret to store KES server configuration - kesConfigurationSecretName := fmt.Sprintf("%s-kes-configuration", secretName) - kesConfigurationSecret := corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: kesConfigurationSecretName, - }, - Immutable: &imm, - Data: map[string][]byte{ - "server-config.yaml": serverConfigYaml, - }, - } - _, err = clientset.CoreV1().Secrets(ns).Create(ctx, &kesConfigurationSecret, metav1.CreateOptions{}) - if err != nil { - return nil, err - } - // Configuration used by KES - minInst.Spec.KES.Configuration = &corev1.LocalObjectReference{ - Name: kesConfigurationSecretName, - } + // KES client mTLSCertificates used by MinIO instance + minInst.Spec.ExternalClientCertSecret, err = getTenantExternalClientCertificates(ctx, clientset, ns, tenantReq.Encryption, secretName) + if err != nil { + return nil, err + } + // KES configuration for Tenant instance + minInst.Spec.KES, err = getKESConfiguration(ctx, clientset, ns, tenantReq.Encryption, secretName, minInst.Spec.RequestAutoCert) + if err != nil { + return nil, err } } @@ -1507,3 +1305,328 @@ func parseNodeSelectorTerm(term *corev1.NodeSelectorTerm) *models.NodeSelectorTe } return &t } + +func getTenantExternalClientCertificates(ctx context.Context, clientSet *kubernetes.Clientset, ns string, encryptionCfg *models.EncryptionConfiguration, secretName string) (clientCertificates *operator.LocalCertificateReference, err error) { + instanceExternalClientCertificateSecretName := fmt.Sprintf("%s-instance-external-client-mtls-certificates", secretName) + // If there's an error during this process we delete all KES configuration secrets + defer func() { + if err != nil { + errDelete := clientSet.CoreV1().Secrets(ns).Delete(ctx, instanceExternalClientCertificateSecretName, metav1.DeleteOptions{}) + if errDelete != nil { + log.Print(errDelete) + } + return + } + }() + imm := true + // Secret to store KES clients TLS mTLSCertificates (mTLS authentication) + clientTLSCrt, err := base64.StdEncoding.DecodeString(*encryptionCfg.Client.Crt) + if err != nil { + return nil, err + } + clientTLSKey, err := base64.StdEncoding.DecodeString(*encryptionCfg.Client.Key) + if err != nil { + return nil, err + } + instanceExternalClientCertificateSecret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: instanceExternalClientCertificateSecretName, + }, + Type: corev1.SecretTypeTLS, + Immutable: &imm, + Data: map[string][]byte{ + "tls.crt": clientTLSCrt, + "tls.key": clientTLSKey, + }, + } + _, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &instanceExternalClientCertificateSecret, metav1.CreateOptions{}) + if err != nil { + return nil, err + } + // KES client mTLSCertificates used by MinIO instance + clientCertificates = &operator.LocalCertificateReference{ + Name: instanceExternalClientCertificateSecretName, + Type: "kubernetes.io/tls", + } + return clientCertificates, nil +} + +func getKESConfiguration(ctx context.Context, clientSet *kubernetes.Clientset, ns string, encryptionCfg *models.EncryptionConfiguration, secretName string, autoCert bool) (kesConfiguration *operator.KESConfig, err error) { + // secrets used by the KES configuration + instanceExternalClientCertificateSecretName := fmt.Sprintf("%s-instance-external-client-mtls-certificates", secretName) + kesExternalCertificateSecretName := fmt.Sprintf("%s-kes-external-mtls-certificates", secretName) + kesClientCertSecretName := fmt.Sprintf("%s-kes-mtls-certificates", secretName) + kesConfigurationSecretName := fmt.Sprintf("%s-kes-configuration", secretName) + // If there's an error during this process we delete all KES configuration secrets + defer func() { + if err != nil { + errDelete := clientSet.CoreV1().Secrets(ns).Delete(ctx, instanceExternalClientCertificateSecretName, metav1.DeleteOptions{}) + if errDelete != nil { + log.Print(errDelete) + } + errDelete = clientSet.CoreV1().Secrets(ns).Delete(ctx, kesExternalCertificateSecretName, metav1.DeleteOptions{}) + if errDelete != nil { + log.Print(errDelete) + } + errDelete = clientSet.CoreV1().Secrets(ns).Delete(ctx, kesClientCertSecretName, metav1.DeleteOptions{}) + if errDelete != nil { + log.Print(errDelete) + } + errDelete = clientSet.CoreV1().Secrets(ns).Delete(ctx, kesConfigurationSecretName, metav1.DeleteOptions{}) + if errDelete != nil { + log.Print(errDelete) + } + return + } + }() + + imm := true + kesConfiguration = &operator.KESConfig{ + Image: "minio/kes:v0.11.0", + Replicas: 1, + Metadata: nil, + } + // Using custom image for KES + if encryptionCfg.Image != "" { + kesConfiguration.Image = encryptionCfg.Image + } + // if autoCert is enabled then Operator will generate the client certificates, calculate the client cert identity + // and pass it to KES via the $MINIO_KES_IDENTITY variable + clientCrtIdentity := "$MINIO_KES_IDENTITY" + // Generate server certificates for KES only if autoCert is disabled + if !autoCert { + serverTLSCrt, err := base64.StdEncoding.DecodeString(*encryptionCfg.Server.Crt) + if err != nil { + return nil, err + } + serverTLSKey, err := base64.StdEncoding.DecodeString(*encryptionCfg.Server.Key) + if err != nil { + return nil, err + } + // Secret to store KES server TLS mTLSCertificates + kesExternalCertificateSecret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: kesExternalCertificateSecretName, + }, + Type: corev1.SecretTypeTLS, + Immutable: &imm, + Data: map[string][]byte{ + "tls.crt": serverTLSCrt, + "tls.key": serverTLSKey, + }, + } + _, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &kesExternalCertificateSecret, metav1.CreateOptions{}) + if err != nil { + return nil, err + } + // External mTLSCertificates used by KES + kesConfiguration.ExternalCertSecret = &operator.LocalCertificateReference{ + Name: kesExternalCertificateSecretName, + Type: "kubernetes.io/tls", + } + + // Client certificate for KES used by Minio to mTLS + clientTLSCrt, err := base64.StdEncoding.DecodeString(*encryptionCfg.Client.Crt) + if err != nil { + return nil, err + } + // Calculate the client cert identity based on the clientTLSCrt + h := crypto.SHA256.New() + certificate, err := kes.ParseCertificate(clientTLSCrt) + if err != nil { + return nil, err + } + h.Write(certificate.RawSubjectPublicKeyInfo) + clientCrtIdentity = hex.EncodeToString(h.Sum(nil)) + } + + // Default kesConfiguration for KES + kesConfig := kes.ServerConfig{ + Addr: "0.0.0.0:7373", + Root: "disabled", + TLS: kes.TLS{ + KeyPath: "/tmp/kes/server.key", + CertPath: "/tmp/kes/server.crt", + }, + Policies: map[string]kes.Policy{ + "default-policy": { + Paths: []string{ + "/v1/key/create/my-minio-key", + "/v1/key/generate/my-minio-key", + "/v1/key/decrypt/my-minio-key", + }, + Identities: []kes.Identity{ + kes.Identity(clientCrtIdentity), + }, + }, + }, + Cache: kes.Cache{ + Expiry: &kes.Expiry{ + Any: 5 * time.Minute, + Unused: 20 * time.Second, + }, + }, + Log: kes.Log{ + Error: "on", + Audit: "off", + }, + Keys: kes.Keys{}, + } + + // operator will mount the mTLSCertificates in the following paths + // therefore we set these values in the KES yaml kesConfiguration + var mTLSClientCrtPath = "/tmp/kes/client.crt" + var mTLSClientKeyPath = "/tmp/kes/client.key" + var mTLSClientCaPath = "/tmp/kes/ca.crt" + // map to hold mTLSCertificates for KES mTLS against Vault + mTLSCertificates := map[string][]byte{} + + // if encryption is enabled and encryption is configured to use Vault + if encryptionCfg.Vault != nil { + // Initialize Vault Config + + kesConfig.Keys.Vault = &kes.Vault{ + Endpoint: *encryptionCfg.Vault.Endpoint, + EnginePath: encryptionCfg.Vault.Engine, + Namespace: encryptionCfg.Vault.Namespace, + Prefix: encryptionCfg.Vault.Prefix, + Status: &kes.VaultStatus{ + Ping: 10 * time.Second, + }, + } + // Vault AppRole credentials + if encryptionCfg.Vault.Approle != nil { + kesConfig.Keys.Vault.AppRole = &kes.AppRole{ + EnginePath: encryptionCfg.Vault.Approle.Engine, + ID: *encryptionCfg.Vault.Approle.ID, + Secret: *encryptionCfg.Vault.Approle.Secret, + Retry: 15 * time.Second, + } + } else { + return nil, errors.New("approle credentials missing for kes") + } + + // Vault mTLS kesConfiguration + if encryptionCfg.Vault.TLS != nil { + vaultTLSConfig := encryptionCfg.Vault.TLS + if vaultTLSConfig.Crt != "" { + clientCrt, err := base64.StdEncoding.DecodeString(vaultTLSConfig.Crt) + if err != nil { + return nil, err + } + mTLSCertificates["client.crt"] = clientCrt + kesConfig.Keys.Vault.TLS.CertPath = mTLSClientCrtPath + } + if vaultTLSConfig.Key != "" { + clientKey, err := base64.StdEncoding.DecodeString(vaultTLSConfig.Key) + if err != nil { + return nil, err + } + mTLSCertificates["client.key"] = clientKey + kesConfig.Keys.Vault.TLS.KeyPath = mTLSClientKeyPath + } + if vaultTLSConfig.Ca != "" { + caCrt, err := base64.StdEncoding.DecodeString(vaultTLSConfig.Ca) + if err != nil { + return nil, err + } + mTLSCertificates["ca.crt"] = caCrt + kesConfig.Keys.Vault.TLS.CAPath = mTLSClientCaPath + } + } + } else if encryptionCfg.Aws != nil { + // Initialize AWS + kesConfig.Keys.Aws = &kes.Aws{ + SecretsManager: &kes.AwsSecretManager{}, + } + // AWS basic kesConfiguration + if encryptionCfg.Aws.Secretsmanager != nil { + kesConfig.Keys.Aws.SecretsManager.Endpoint = *encryptionCfg.Aws.Secretsmanager.Endpoint + kesConfig.Keys.Aws.SecretsManager.Region = *encryptionCfg.Aws.Secretsmanager.Region + kesConfig.Keys.Aws.SecretsManager.KmsKey = encryptionCfg.Aws.Secretsmanager.Kmskey + // AWS credentials + if encryptionCfg.Aws.Secretsmanager.Credentials != nil { + kesConfig.Keys.Aws.SecretsManager.Login = &kes.AwsSecretManagerLogin{ + AccessKey: *encryptionCfg.Aws.Secretsmanager.Credentials.Accesskey, + SecretKey: *encryptionCfg.Aws.Secretsmanager.Credentials.Secretkey, + SessionToken: encryptionCfg.Aws.Secretsmanager.Credentials.Token, + } + } + } + } else if encryptionCfg.Gemalto != nil { + // Initialize Gemalto + kesConfig.Keys.Gemalto = &kes.Gemalto{ + KeySecure: &kes.GemaltoKeySecure{}, + } + // Gemalto Configuration + if encryptionCfg.Gemalto.Keysecure != nil { + kesConfig.Keys.Gemalto.KeySecure.Endpoint = *encryptionCfg.Gemalto.Keysecure.Endpoint + // Gemalto TLS kesConfiguration + if encryptionCfg.Gemalto.Keysecure.TLS != nil { + if encryptionCfg.Gemalto.Keysecure.TLS.Ca != nil { + caCrt, err := base64.StdEncoding.DecodeString(*encryptionCfg.Gemalto.Keysecure.TLS.Ca) + if err != nil { + return nil, err + } + mTLSCertificates["ca.crt"] = caCrt + kesConfig.Keys.Gemalto.KeySecure.TLS = &kes.GemaltoTLS{ + CAPath: mTLSClientCaPath, + } + } + } + // Gemalto Login + if encryptionCfg.Gemalto.Keysecure.Credentials != nil { + kesConfig.Keys.Gemalto.KeySecure.Credentials = &kes.GemaltoCredentials{ + Token: *encryptionCfg.Gemalto.Keysecure.Credentials.Token, + Domain: *encryptionCfg.Gemalto.Keysecure.Credentials.Domain, + Retry: 15 * time.Second, + } + } + } + } + + // if mTLSCertificates contains elements we create the kubernetes secret + if len(mTLSCertificates) > 0 { + // Secret to store KES mTLS kesConfiguration + kesClientCertSecret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: kesClientCertSecretName, + }, + Immutable: &imm, + Data: mTLSCertificates, + } + _, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &kesClientCertSecret, metav1.CreateOptions{}) + if err != nil { + return nil, err + } + // kubernetes generic secret + kesConfiguration.ClientCertSecret = &operator.LocalCertificateReference{ + Name: kesClientCertSecretName, + } + } + + // Generate Yaml kesConfiguration for KES + serverConfigYaml, err := yaml.Marshal(kesConfig) + if err != nil { + return nil, err + } + // Secret to store KES server kesConfiguration + kesConfigurationSecret := corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: kesConfigurationSecretName, + }, + Immutable: &imm, + Data: map[string][]byte{ + "server-config.yaml": serverConfigYaml, + }, + } + _, err = clientSet.CoreV1().Secrets(ns).Create(ctx, &kesConfigurationSecret, metav1.CreateOptions{}) + if err != nil { + return nil, err + } + // Configuration used by KES + kesConfiguration.Configuration = &corev1.LocalObjectReference{ + Name: kesConfigurationSecretName, + } + return kesConfiguration, nil +} diff --git a/restapi/embedded_spec.go b/restapi/embedded_spec.go index 1b5780967..b264a5377 100644 --- a/restapi/embedded_spec.go +++ b/restapi/embedded_spec.go @@ -2128,9 +2128,6 @@ func init() { "image": { "type": "string" }, - "master_key": { - "type": "string" - }, "server": { "type": "object", "required": [ @@ -3181,6 +3178,20 @@ func init() { "format": "int64" } } + }, + "tls": { + "type": "object", + "properties": { + "ca": { + "type": "string" + }, + "crt": { + "type": "string" + }, + "key": { + "type": "string" + } + } } } }, @@ -5528,6 +5539,20 @@ func init() { } } }, + "VaultConfigurationTLS": { + "type": "object", + "properties": { + "ca": { + "type": "string" + }, + "crt": { + "type": "string" + }, + "key": { + "type": "string" + } + } + }, "ZoneAffinityNodeAffinity": { "description": "Describes node affinity scheduling rules for the pod.", "type": "object", @@ -6056,9 +6081,6 @@ func init() { "image": { "type": "string" }, - "master_key": { - "type": "string" - }, "server": { "type": "object", "required": [ @@ -7043,6 +7065,20 @@ func init() { "format": "int64" } } + }, + "tls": { + "type": "object", + "properties": { + "ca": { + "type": "string" + }, + "crt": { + "type": "string" + }, + "key": { + "type": "string" + } + } } } }, diff --git a/swagger.yml b/swagger.yml index 5d64bf21b..21aac9df0 100644 --- a/swagger.yml +++ b/swagger.yml @@ -1921,8 +1921,6 @@ definitions: type: string key: type: string - master_key: - type: string gemalto: type: object $ref: "#/definitions/gemaltoConfiguration" @@ -1968,6 +1966,15 @@ definitions: ping: type: integer format: int64 + tls: + type: object + properties: + key: + type: string + crt: + type: string + ca: + type: string awsConfiguration: type: object