diff --git a/models/encryption_configuration.go b/models/encryption_configuration.go index 27fe046d5..d0d4e621c 100644 --- a/models/encryption_configuration.go +++ b/models/encryption_configuration.go @@ -57,6 +57,9 @@ type EncryptionConfiguration struct { // replicas Replicas string `json:"replicas,omitempty"` + // secrets to be deleted + SecretsToBeDeleted []string `json:"secretsToBeDeleted"` + // security context SecurityContext *SecurityContext `json:"securityContext,omitempty"` @@ -92,6 +95,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error { Replicas string `json:"replicas,omitempty"` + SecretsToBeDeleted []string `json:"secretsToBeDeleted"` + SecurityContext *SecurityContext `json:"securityContext,omitempty"` Server *KeyPairConfiguration `json:"server,omitempty"` @@ -116,6 +121,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error { m.Replicas = dataAO1.Replicas + m.SecretsToBeDeleted = dataAO1.SecretsToBeDeleted + m.SecurityContext = dataAO1.SecurityContext m.Server = dataAO1.Server @@ -149,6 +156,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) { Replicas string `json:"replicas,omitempty"` + SecretsToBeDeleted []string `json:"secretsToBeDeleted"` + SecurityContext *SecurityContext `json:"securityContext,omitempty"` Server *KeyPairConfiguration `json:"server,omitempty"` @@ -170,6 +179,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) { dataAO1.Replicas = m.Replicas + dataAO1.SecretsToBeDeleted = m.SecretsToBeDeleted + dataAO1.SecurityContext = m.SecurityContext dataAO1.Server = m.Server diff --git a/models/encryption_configuration_response.go b/models/encryption_configuration_response.go new file mode 100644 index 000000000..0c17e89b6 --- /dev/null +++ b/models/encryption_configuration_response.go @@ -0,0 +1,585 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// EncryptionConfigurationResponse encryption configuration response +// +// swagger:model encryptionConfigurationResponse +type EncryptionConfigurationResponse struct { + MetadataFields + + // aws + Aws *AwsConfiguration `json:"aws,omitempty"` + + // azure + Azure *AzureConfiguration `json:"azure,omitempty"` + + // gcp + Gcp *GcpConfiguration `json:"gcp,omitempty"` + + // gemalto + Gemalto *GemaltoConfigurationResponse `json:"gemalto,omitempty"` + + // image + Image string `json:"image,omitempty"` + + // mtls client + MtlsClient *CertificateInfo `json:"mtls_client,omitempty"` + + // replicas + Replicas string `json:"replicas,omitempty"` + + // security context + SecurityContext *SecurityContext `json:"securityContext,omitempty"` + + // server + Server *CertificateInfo `json:"server,omitempty"` + + // vault + Vault *VaultConfigurationResponse `json:"vault,omitempty"` +} + +// UnmarshalJSON unmarshals this object from a JSON structure +func (m *EncryptionConfigurationResponse) UnmarshalJSON(raw []byte) error { + // AO0 + var aO0 MetadataFields + if err := swag.ReadJSON(raw, &aO0); err != nil { + return err + } + m.MetadataFields = aO0 + + // AO1 + var dataAO1 struct { + Aws *AwsConfiguration `json:"aws,omitempty"` + + Azure *AzureConfiguration `json:"azure,omitempty"` + + Gcp *GcpConfiguration `json:"gcp,omitempty"` + + Gemalto *GemaltoConfigurationResponse `json:"gemalto,omitempty"` + + Image string `json:"image,omitempty"` + + MtlsClient *CertificateInfo `json:"mtls_client,omitempty"` + + Replicas string `json:"replicas,omitempty"` + + SecurityContext *SecurityContext `json:"securityContext,omitempty"` + + Server *CertificateInfo `json:"server,omitempty"` + + Vault *VaultConfigurationResponse `json:"vault,omitempty"` + } + if err := swag.ReadJSON(raw, &dataAO1); err != nil { + return err + } + + m.Aws = dataAO1.Aws + + m.Azure = dataAO1.Azure + + m.Gcp = dataAO1.Gcp + + m.Gemalto = dataAO1.Gemalto + + m.Image = dataAO1.Image + + m.MtlsClient = dataAO1.MtlsClient + + m.Replicas = dataAO1.Replicas + + m.SecurityContext = dataAO1.SecurityContext + + m.Server = dataAO1.Server + + m.Vault = dataAO1.Vault + + return nil +} + +// MarshalJSON marshals this object to a JSON structure +func (m EncryptionConfigurationResponse) MarshalJSON() ([]byte, error) { + _parts := make([][]byte, 0, 2) + + aO0, err := swag.WriteJSON(m.MetadataFields) + if err != nil { + return nil, err + } + _parts = append(_parts, aO0) + var dataAO1 struct { + Aws *AwsConfiguration `json:"aws,omitempty"` + + Azure *AzureConfiguration `json:"azure,omitempty"` + + Gcp *GcpConfiguration `json:"gcp,omitempty"` + + Gemalto *GemaltoConfigurationResponse `json:"gemalto,omitempty"` + + Image string `json:"image,omitempty"` + + MtlsClient *CertificateInfo `json:"mtls_client,omitempty"` + + Replicas string `json:"replicas,omitempty"` + + SecurityContext *SecurityContext `json:"securityContext,omitempty"` + + Server *CertificateInfo `json:"server,omitempty"` + + Vault *VaultConfigurationResponse `json:"vault,omitempty"` + } + + dataAO1.Aws = m.Aws + + dataAO1.Azure = m.Azure + + dataAO1.Gcp = m.Gcp + + dataAO1.Gemalto = m.Gemalto + + dataAO1.Image = m.Image + + dataAO1.MtlsClient = m.MtlsClient + + dataAO1.Replicas = m.Replicas + + dataAO1.SecurityContext = m.SecurityContext + + dataAO1.Server = m.Server + + dataAO1.Vault = m.Vault + + jsonDataAO1, errAO1 := swag.WriteJSON(dataAO1) + if errAO1 != nil { + return nil, errAO1 + } + _parts = append(_parts, jsonDataAO1) + return swag.ConcatJSON(_parts...), nil +} + +// Validate validates this encryption configuration response +func (m *EncryptionConfigurationResponse) Validate(formats strfmt.Registry) error { + var res []error + + // validation for a type composition with MetadataFields + if err := m.MetadataFields.Validate(formats); err != nil { + res = append(res, err) + } + + if err := m.validateAws(formats); err != nil { + res = append(res, err) + } + + if err := m.validateAzure(formats); err != nil { + res = append(res, err) + } + + if err := m.validateGcp(formats); err != nil { + res = append(res, err) + } + + if err := m.validateGemalto(formats); err != nil { + res = append(res, err) + } + + if err := m.validateMtlsClient(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSecurityContext(formats); err != nil { + res = append(res, err) + } + + if err := m.validateServer(formats); err != nil { + res = append(res, err) + } + + if err := m.validateVault(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *EncryptionConfigurationResponse) validateAws(formats strfmt.Registry) error { + + if swag.IsZero(m.Aws) { // not required + return nil + } + + if m.Aws != nil { + if err := m.Aws.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("aws") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("aws") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) validateAzure(formats strfmt.Registry) error { + + if swag.IsZero(m.Azure) { // not required + return nil + } + + if m.Azure != nil { + if err := m.Azure.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("azure") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("azure") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) validateGcp(formats strfmt.Registry) error { + + if swag.IsZero(m.Gcp) { // not required + return nil + } + + if m.Gcp != nil { + if err := m.Gcp.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("gcp") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("gcp") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) validateGemalto(formats strfmt.Registry) error { + + if swag.IsZero(m.Gemalto) { // not required + return nil + } + + if m.Gemalto != nil { + if err := m.Gemalto.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("gemalto") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("gemalto") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) validateMtlsClient(formats strfmt.Registry) error { + + if swag.IsZero(m.MtlsClient) { // not required + return nil + } + + if m.MtlsClient != nil { + if err := m.MtlsClient.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("mtls_client") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("mtls_client") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) validateSecurityContext(formats strfmt.Registry) error { + + if swag.IsZero(m.SecurityContext) { // not required + return nil + } + + if m.SecurityContext != nil { + if err := m.SecurityContext.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("securityContext") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("securityContext") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) validateServer(formats strfmt.Registry) error { + + if swag.IsZero(m.Server) { // not required + return nil + } + + if m.Server != nil { + if err := m.Server.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("server") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("server") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) validateVault(formats strfmt.Registry) error { + + if swag.IsZero(m.Vault) { // not required + return nil + } + + if m.Vault != nil { + if err := m.Vault.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("vault") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("vault") + } + return err + } + } + + return nil +} + +// ContextValidate validate this encryption configuration response based on the context it is used +func (m *EncryptionConfigurationResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + // validation for a type composition with MetadataFields + if err := m.MetadataFields.ContextValidate(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateAws(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateAzure(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateGcp(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateGemalto(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateMtlsClient(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateSecurityContext(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateServer(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateVault(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *EncryptionConfigurationResponse) contextValidateAws(ctx context.Context, formats strfmt.Registry) error { + + if m.Aws != nil { + if err := m.Aws.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("aws") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("aws") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) contextValidateAzure(ctx context.Context, formats strfmt.Registry) error { + + if m.Azure != nil { + if err := m.Azure.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("azure") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("azure") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) contextValidateGcp(ctx context.Context, formats strfmt.Registry) error { + + if m.Gcp != nil { + if err := m.Gcp.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("gcp") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("gcp") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) contextValidateGemalto(ctx context.Context, formats strfmt.Registry) error { + + if m.Gemalto != nil { + if err := m.Gemalto.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("gemalto") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("gemalto") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) contextValidateMtlsClient(ctx context.Context, formats strfmt.Registry) error { + + if m.MtlsClient != nil { + if err := m.MtlsClient.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("mtls_client") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("mtls_client") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) contextValidateSecurityContext(ctx context.Context, formats strfmt.Registry) error { + + if m.SecurityContext != nil { + if err := m.SecurityContext.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("securityContext") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("securityContext") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) contextValidateServer(ctx context.Context, formats strfmt.Registry) error { + + if m.Server != nil { + if err := m.Server.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("server") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("server") + } + return err + } + } + + return nil +} + +func (m *EncryptionConfigurationResponse) contextValidateVault(ctx context.Context, formats strfmt.Registry) error { + + if m.Vault != nil { + if err := m.Vault.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("vault") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("vault") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *EncryptionConfigurationResponse) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *EncryptionConfigurationResponse) UnmarshalBinary(b []byte) error { + var res EncryptionConfigurationResponse + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/gemalto_configuration_response.go b/models/gemalto_configuration_response.go new file mode 100644 index 000000000..6baa77f20 --- /dev/null +++ b/models/gemalto_configuration_response.go @@ -0,0 +1,447 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// GemaltoConfigurationResponse gemalto configuration response +// +// swagger:model gemaltoConfigurationResponse +type GemaltoConfigurationResponse struct { + + // keysecure + // Required: true + Keysecure *GemaltoConfigurationResponseKeysecure `json:"keysecure"` +} + +// Validate validates this gemalto configuration response +func (m *GemaltoConfigurationResponse) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateKeysecure(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *GemaltoConfigurationResponse) validateKeysecure(formats strfmt.Registry) error { + + if err := validate.Required("keysecure", "body", m.Keysecure); err != nil { + return err + } + + if m.Keysecure != nil { + if err := m.Keysecure.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("keysecure") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("keysecure") + } + return err + } + } + + return nil +} + +// ContextValidate validate this gemalto configuration response based on the context it is used +func (m *GemaltoConfigurationResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateKeysecure(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *GemaltoConfigurationResponse) contextValidateKeysecure(ctx context.Context, formats strfmt.Registry) error { + + if m.Keysecure != nil { + if err := m.Keysecure.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("keysecure") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("keysecure") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *GemaltoConfigurationResponse) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *GemaltoConfigurationResponse) UnmarshalBinary(b []byte) error { + var res GemaltoConfigurationResponse + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// GemaltoConfigurationResponseKeysecure gemalto configuration response keysecure +// +// swagger:model GemaltoConfigurationResponseKeysecure +type GemaltoConfigurationResponseKeysecure struct { + + // credentials + // Required: true + Credentials *GemaltoConfigurationResponseKeysecureCredentials `json:"credentials"` + + // endpoint + // Required: true + Endpoint *string `json:"endpoint"` + + // tls + TLS *GemaltoConfigurationResponseKeysecureTLS `json:"tls,omitempty"` +} + +// Validate validates this gemalto configuration response keysecure +func (m *GemaltoConfigurationResponseKeysecure) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateCredentials(formats); err != nil { + res = append(res, err) + } + + if err := m.validateEndpoint(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTLS(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *GemaltoConfigurationResponseKeysecure) validateCredentials(formats strfmt.Registry) error { + + if err := validate.Required("keysecure"+"."+"credentials", "body", m.Credentials); err != nil { + return err + } + + if m.Credentials != nil { + if err := m.Credentials.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("keysecure" + "." + "credentials") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("keysecure" + "." + "credentials") + } + return err + } + } + + return nil +} + +func (m *GemaltoConfigurationResponseKeysecure) validateEndpoint(formats strfmt.Registry) error { + + if err := validate.Required("keysecure"+"."+"endpoint", "body", m.Endpoint); err != nil { + return err + } + + return nil +} + +func (m *GemaltoConfigurationResponseKeysecure) 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("keysecure" + "." + "tls") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("keysecure" + "." + "tls") + } + return err + } + } + + return nil +} + +// ContextValidate validate this gemalto configuration response keysecure based on the context it is used +func (m *GemaltoConfigurationResponseKeysecure) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateCredentials(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateTLS(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *GemaltoConfigurationResponseKeysecure) contextValidateCredentials(ctx context.Context, formats strfmt.Registry) error { + + if m.Credentials != nil { + if err := m.Credentials.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("keysecure" + "." + "credentials") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("keysecure" + "." + "credentials") + } + return err + } + } + + return nil +} + +func (m *GemaltoConfigurationResponseKeysecure) contextValidateTLS(ctx context.Context, formats strfmt.Registry) error { + + if m.TLS != nil { + if err := m.TLS.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("keysecure" + "." + "tls") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("keysecure" + "." + "tls") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *GemaltoConfigurationResponseKeysecure) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *GemaltoConfigurationResponseKeysecure) UnmarshalBinary(b []byte) error { + var res GemaltoConfigurationResponseKeysecure + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// GemaltoConfigurationResponseKeysecureCredentials gemalto configuration response keysecure credentials +// +// swagger:model GemaltoConfigurationResponseKeysecureCredentials +type GemaltoConfigurationResponseKeysecureCredentials struct { + + // domain + // Required: true + Domain *string `json:"domain"` + + // retry + Retry int64 `json:"retry,omitempty"` + + // token + // Required: true + Token *string `json:"token"` +} + +// Validate validates this gemalto configuration response keysecure credentials +func (m *GemaltoConfigurationResponseKeysecureCredentials) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateDomain(formats); err != nil { + res = append(res, err) + } + + if err := m.validateToken(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *GemaltoConfigurationResponseKeysecureCredentials) validateDomain(formats strfmt.Registry) error { + + if err := validate.Required("keysecure"+"."+"credentials"+"."+"domain", "body", m.Domain); err != nil { + return err + } + + return nil +} + +func (m *GemaltoConfigurationResponseKeysecureCredentials) validateToken(formats strfmt.Registry) error { + + if err := validate.Required("keysecure"+"."+"credentials"+"."+"token", "body", m.Token); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this gemalto configuration response keysecure credentials based on context it is used +func (m *GemaltoConfigurationResponseKeysecureCredentials) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *GemaltoConfigurationResponseKeysecureCredentials) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *GemaltoConfigurationResponseKeysecureCredentials) UnmarshalBinary(b []byte) error { + var res GemaltoConfigurationResponseKeysecureCredentials + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// GemaltoConfigurationResponseKeysecureTLS gemalto configuration response keysecure TLS +// +// swagger:model GemaltoConfigurationResponseKeysecureTLS +type GemaltoConfigurationResponseKeysecureTLS struct { + + // ca + // Required: true + Ca *CertificateInfo `json:"ca"` +} + +// Validate validates this gemalto configuration response keysecure TLS +func (m *GemaltoConfigurationResponseKeysecureTLS) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateCa(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *GemaltoConfigurationResponseKeysecureTLS) validateCa(formats strfmt.Registry) error { + + if err := validate.Required("keysecure"+"."+"tls"+"."+"ca", "body", m.Ca); err != nil { + return err + } + + if m.Ca != nil { + if err := m.Ca.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("keysecure" + "." + "tls" + "." + "ca") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("keysecure" + "." + "tls" + "." + "ca") + } + return err + } + } + + return nil +} + +// ContextValidate validate this gemalto configuration response keysecure TLS based on the context it is used +func (m *GemaltoConfigurationResponseKeysecureTLS) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateCa(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *GemaltoConfigurationResponseKeysecureTLS) contextValidateCa(ctx context.Context, formats strfmt.Registry) error { + + if m.Ca != nil { + if err := m.Ca.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("keysecure" + "." + "tls" + "." + "ca") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("keysecure" + "." + "tls" + "." + "ca") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *GemaltoConfigurationResponseKeysecureTLS) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *GemaltoConfigurationResponseKeysecureTLS) UnmarshalBinary(b []byte) error { + var res GemaltoConfigurationResponseKeysecureTLS + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/update_tenant_encryption_request.go b/models/update_tenant_encryption_request.go new file mode 100644 index 000000000..34934b743 --- /dev/null +++ b/models/update_tenant_encryption_request.go @@ -0,0 +1,232 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + "strconv" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" +) + +// UpdateTenantEncryptionRequest update tenant encryption request +// +// swagger:model updateTenantEncryptionRequest +type UpdateTenantEncryptionRequest struct { + + // auto cert + AutoCert bool `json:"autoCert,omitempty"` + + // custom certificates + CustomCertificates *UpdateTenantEncryptionRequestCustomCertificates `json:"customCertificates,omitempty"` +} + +// Validate validates this update tenant encryption request +func (m *UpdateTenantEncryptionRequest) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateCustomCertificates(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *UpdateTenantEncryptionRequest) validateCustomCertificates(formats strfmt.Registry) error { + if swag.IsZero(m.CustomCertificates) { // not required + return nil + } + + if m.CustomCertificates != nil { + if err := m.CustomCertificates.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("customCertificates") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("customCertificates") + } + return err + } + } + + return nil +} + +// ContextValidate validate this update tenant encryption request based on the context it is used +func (m *UpdateTenantEncryptionRequest) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateCustomCertificates(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *UpdateTenantEncryptionRequest) contextValidateCustomCertificates(ctx context.Context, formats strfmt.Registry) error { + + if m.CustomCertificates != nil { + if err := m.CustomCertificates.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("customCertificates") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("customCertificates") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *UpdateTenantEncryptionRequest) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *UpdateTenantEncryptionRequest) UnmarshalBinary(b []byte) error { + var res UpdateTenantEncryptionRequest + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// UpdateTenantEncryptionRequestCustomCertificates update tenant encryption request custom certificates +// +// swagger:model UpdateTenantEncryptionRequestCustomCertificates +type UpdateTenantEncryptionRequestCustomCertificates struct { + + // minio + Minio []*KeyPairConfiguration `json:"minio"` + + // minio c as + MinioCAs []string `json:"minioCAs"` + + // secrets to be deleted + SecretsToBeDeleted []string `json:"secretsToBeDeleted"` +} + +// Validate validates this update tenant encryption request custom certificates +func (m *UpdateTenantEncryptionRequestCustomCertificates) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateMinio(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *UpdateTenantEncryptionRequestCustomCertificates) validateMinio(formats strfmt.Registry) error { + if swag.IsZero(m.Minio) { // not required + return nil + } + + for i := 0; i < len(m.Minio); i++ { + if swag.IsZero(m.Minio[i]) { // not required + continue + } + + if m.Minio[i] != nil { + if err := m.Minio[i].Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("customCertificates" + "." + "minio" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("customCertificates" + "." + "minio" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// ContextValidate validate this update tenant encryption request custom certificates based on the context it is used +func (m *UpdateTenantEncryptionRequestCustomCertificates) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateMinio(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *UpdateTenantEncryptionRequestCustomCertificates) contextValidateMinio(ctx context.Context, formats strfmt.Registry) error { + + for i := 0; i < len(m.Minio); i++ { + + if m.Minio[i] != nil { + if err := m.Minio[i].ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("customCertificates" + "." + "minio" + "." + strconv.Itoa(i)) + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("customCertificates" + "." + "minio" + "." + strconv.Itoa(i)) + } + return err + } + } + + } + + return nil +} + +// MarshalBinary interface implementation +func (m *UpdateTenantEncryptionRequestCustomCertificates) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *UpdateTenantEncryptionRequestCustomCertificates) UnmarshalBinary(b []byte) error { + var res UpdateTenantEncryptionRequestCustomCertificates + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/vault_configuration_response.go b/models/vault_configuration_response.go new file mode 100644 index 000000000..93742b387 --- /dev/null +++ b/models/vault_configuration_response.go @@ -0,0 +1,494 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package models + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "context" + + "github.com/go-openapi/errors" + "github.com/go-openapi/strfmt" + "github.com/go-openapi/swag" + "github.com/go-openapi/validate" +) + +// VaultConfigurationResponse vault configuration response +// +// swagger:model vaultConfigurationResponse +type VaultConfigurationResponse struct { + + // approle + // Required: true + Approle *VaultConfigurationResponseApprole `json:"approle"` + + // endpoint + // Required: true + Endpoint *string `json:"endpoint"` + + // engine + Engine string `json:"engine,omitempty"` + + // namespace + Namespace string `json:"namespace,omitempty"` + + // prefix + Prefix string `json:"prefix,omitempty"` + + // status + Status *VaultConfigurationResponseStatus `json:"status,omitempty"` + + // tls + TLS *VaultConfigurationResponseTLS `json:"tls,omitempty"` +} + +// Validate validates this vault configuration response +func (m *VaultConfigurationResponse) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateApprole(formats); err != nil { + res = append(res, err) + } + + if err := m.validateEndpoint(formats); err != nil { + res = append(res, err) + } + + if err := m.validateStatus(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTLS(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *VaultConfigurationResponse) validateApprole(formats strfmt.Registry) error { + + if err := validate.Required("approle", "body", m.Approle); err != nil { + return err + } + + if m.Approle != nil { + if err := m.Approle.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("approle") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("approle") + } + return err + } + } + + return nil +} + +func (m *VaultConfigurationResponse) validateEndpoint(formats strfmt.Registry) error { + + if err := validate.Required("endpoint", "body", m.Endpoint); err != nil { + return err + } + + return nil +} + +func (m *VaultConfigurationResponse) validateStatus(formats strfmt.Registry) error { + if swag.IsZero(m.Status) { // not required + return nil + } + + if m.Status != nil { + if err := m.Status.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + } + + return nil +} + +func (m *VaultConfigurationResponse) 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") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("tls") + } + return err + } + } + + return nil +} + +// ContextValidate validate this vault configuration response based on the context it is used +func (m *VaultConfigurationResponse) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateApprole(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateStatus(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateTLS(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *VaultConfigurationResponse) contextValidateApprole(ctx context.Context, formats strfmt.Registry) error { + + if m.Approle != nil { + if err := m.Approle.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("approle") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("approle") + } + return err + } + } + + return nil +} + +func (m *VaultConfigurationResponse) contextValidateStatus(ctx context.Context, formats strfmt.Registry) error { + + if m.Status != nil { + if err := m.Status.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("status") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("status") + } + return err + } + } + + return nil +} + +func (m *VaultConfigurationResponse) contextValidateTLS(ctx context.Context, formats strfmt.Registry) error { + + if m.TLS != nil { + if err := m.TLS.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("tls") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("tls") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *VaultConfigurationResponse) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *VaultConfigurationResponse) UnmarshalBinary(b []byte) error { + var res VaultConfigurationResponse + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// VaultConfigurationResponseApprole vault configuration response approle +// +// swagger:model VaultConfigurationResponseApprole +type VaultConfigurationResponseApprole struct { + + // engine + Engine string `json:"engine,omitempty"` + + // id + // Required: true + ID *string `json:"id"` + + // retry + Retry int64 `json:"retry,omitempty"` + + // secret + // Required: true + Secret *string `json:"secret"` +} + +// Validate validates this vault configuration response approle +func (m *VaultConfigurationResponseApprole) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateSecret(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *VaultConfigurationResponseApprole) validateID(formats strfmt.Registry) error { + + if err := validate.Required("approle"+"."+"id", "body", m.ID); err != nil { + return err + } + + return nil +} + +func (m *VaultConfigurationResponseApprole) validateSecret(formats strfmt.Registry) error { + + if err := validate.Required("approle"+"."+"secret", "body", m.Secret); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this vault configuration response approle based on context it is used +func (m *VaultConfigurationResponseApprole) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *VaultConfigurationResponseApprole) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *VaultConfigurationResponseApprole) UnmarshalBinary(b []byte) error { + var res VaultConfigurationResponseApprole + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// VaultConfigurationResponseStatus vault configuration response status +// +// swagger:model VaultConfigurationResponseStatus +type VaultConfigurationResponseStatus struct { + + // ping + Ping int64 `json:"ping,omitempty"` +} + +// Validate validates this vault configuration response status +func (m *VaultConfigurationResponseStatus) Validate(formats strfmt.Registry) error { + return nil +} + +// ContextValidate validates this vault configuration response status based on context it is used +func (m *VaultConfigurationResponseStatus) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *VaultConfigurationResponseStatus) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *VaultConfigurationResponseStatus) UnmarshalBinary(b []byte) error { + var res VaultConfigurationResponseStatus + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// VaultConfigurationResponseTLS vault configuration response TLS +// +// swagger:model VaultConfigurationResponseTLS +type VaultConfigurationResponseTLS struct { + + // ca + Ca *CertificateInfo `json:"ca,omitempty"` + + // crt + Crt *CertificateInfo `json:"crt,omitempty"` +} + +// Validate validates this vault configuration response TLS +func (m *VaultConfigurationResponseTLS) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateCa(formats); err != nil { + res = append(res, err) + } + + if err := m.validateCrt(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *VaultConfigurationResponseTLS) validateCa(formats strfmt.Registry) error { + if swag.IsZero(m.Ca) { // not required + return nil + } + + if m.Ca != nil { + if err := m.Ca.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("tls" + "." + "ca") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("tls" + "." + "ca") + } + return err + } + } + + return nil +} + +func (m *VaultConfigurationResponseTLS) validateCrt(formats strfmt.Registry) error { + if swag.IsZero(m.Crt) { // not required + return nil + } + + if m.Crt != nil { + if err := m.Crt.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("tls" + "." + "crt") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("tls" + "." + "crt") + } + return err + } + } + + return nil +} + +// ContextValidate validate this vault configuration response TLS based on the context it is used +func (m *VaultConfigurationResponseTLS) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateCa(ctx, formats); err != nil { + res = append(res, err) + } + + if err := m.contextValidateCrt(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *VaultConfigurationResponseTLS) contextValidateCa(ctx context.Context, formats strfmt.Registry) error { + + if m.Ca != nil { + if err := m.Ca.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("tls" + "." + "ca") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("tls" + "." + "ca") + } + return err + } + } + + return nil +} + +func (m *VaultConfigurationResponseTLS) contextValidateCrt(ctx context.Context, formats strfmt.Registry) error { + + if m.Crt != nil { + if err := m.Crt.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("tls" + "." + "crt") + } else if ce, ok := err.(*errors.CompositeError); ok { + return ce.ValidateName("tls" + "." + "crt") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *VaultConfigurationResponseTLS) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *VaultConfigurationResponseTLS) UnmarshalBinary(b []byte) error { + var res VaultConfigurationResponseTLS + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/operatorapi/embedded_spec.go b/operatorapi/embedded_spec.go index 61419d910..fdb45671b 100644 --- a/operatorapi/embedded_spec.go +++ b/operatorapi/embedded_spec.go @@ -634,6 +634,41 @@ func init() { } }, "/namespaces/{namespace}/tenants/{tenant}/encryption": { + "get": { + "tags": [ + "OperatorAPI" + ], + "summary": "Tenant Encryption Info", + "operationId": "TenantEncryptionInfo", + "parameters": [ + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "tenant", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/encryptionConfigurationResponse" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + }, "put": { "tags": [ "OperatorAPI" @@ -673,6 +708,38 @@ func init() { } } } + }, + "delete": { + "tags": [ + "OperatorAPI" + ], + "summary": "Tenant Delete Encryption", + "operationId": "TenantDeleteEncryption", + "parameters": [ + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "tenant", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "A successful response." + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } } }, "/namespaces/{namespace}/tenants/{tenant}/events": { @@ -2013,6 +2080,12 @@ func init() { "replicas": { "type": "string" }, + "secretsToBeDeleted": { + "type": "array", + "items": { + "type": "string" + } + }, "securityContext": { "type": "object", "$ref": "#/definitions/securityContext" @@ -2029,6 +2102,56 @@ func init() { } ] }, + "encryptionConfigurationResponse": { + "allOf": [ + { + "$ref": "#/definitions/metadataFields" + }, + { + "type": "object", + "properties": { + "aws": { + "type": "object", + "$ref": "#/definitions/awsConfiguration" + }, + "azure": { + "type": "object", + "$ref": "#/definitions/azureConfiguration" + }, + "gcp": { + "type": "object", + "$ref": "#/definitions/gcpConfiguration" + }, + "gemalto": { + "type": "object", + "$ref": "#/definitions/gemaltoConfigurationResponse" + }, + "image": { + "type": "string" + }, + "mtls_client": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + }, + "replicas": { + "type": "string" + }, + "securityContext": { + "type": "object", + "$ref": "#/definitions/securityContext" + }, + "server": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + }, + "vault": { + "type": "object", + "$ref": "#/definitions/vaultConfigurationResponse" + } + } + } + ] + }, "error": { "type": "object", "required": [ @@ -2197,6 +2320,57 @@ func init() { } } }, + "gemaltoConfigurationResponse": { + "type": "object", + "required": [ + "keysecure" + ], + "properties": { + "keysecure": { + "type": "object", + "required": [ + "endpoint", + "credentials" + ], + "properties": { + "credentials": { + "type": "object", + "required": [ + "token", + "domain" + ], + "properties": { + "domain": { + "type": "string" + }, + "retry": { + "type": "integer", + "format": "int64" + }, + "token": { + "type": "string" + } + } + }, + "endpoint": { + "type": "string" + }, + "tls": { + "type": "object", + "required": [ + "ca" + ], + "properties": { + "ca": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + } + } + } + } + } + } + }, "getDirectCSIDriveListResponse": { "type": "object", "properties": { @@ -3648,6 +3822,71 @@ func init() { } } } + }, + "vaultConfigurationResponse": { + "type": "object", + "required": [ + "endpoint", + "approle" + ], + "properties": { + "approle": { + "type": "object", + "required": [ + "id", + "secret" + ], + "properties": { + "engine": { + "type": "string" + }, + "id": { + "type": "string" + }, + "retry": { + "type": "integer", + "format": "int64" + }, + "secret": { + "type": "string" + } + } + }, + "endpoint": { + "type": "string" + }, + "engine": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "status": { + "type": "object", + "properties": { + "ping": { + "type": "integer", + "format": "int64" + } + } + }, + "tls": { + "type": "object", + "properties": { + "ca": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + }, + "crt": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + } + } + } + } } }, "securityDefinitions": { @@ -4264,6 +4503,41 @@ func init() { } }, "/namespaces/{namespace}/tenants/{tenant}/encryption": { + "get": { + "tags": [ + "OperatorAPI" + ], + "summary": "Tenant Encryption Info", + "operationId": "TenantEncryptionInfo", + "parameters": [ + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "tenant", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/encryptionConfigurationResponse" + } + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } + }, "put": { "tags": [ "OperatorAPI" @@ -4303,6 +4577,38 @@ func init() { } } } + }, + "delete": { + "tags": [ + "OperatorAPI" + ], + "summary": "Tenant Delete Encryption", + "operationId": "TenantDeleteEncryption", + "parameters": [ + { + "type": "string", + "name": "namespace", + "in": "path", + "required": true + }, + { + "type": "string", + "name": "tenant", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "A successful response." + }, + "default": { + "description": "Generic error response.", + "schema": { + "$ref": "#/definitions/error" + } + } + } } }, "/namespaces/{namespace}/tenants/{tenant}/events": { @@ -5517,6 +5823,80 @@ func init() { } } }, + "GemaltoConfigurationResponseKeysecure": { + "type": "object", + "required": [ + "endpoint", + "credentials" + ], + "properties": { + "credentials": { + "type": "object", + "required": [ + "token", + "domain" + ], + "properties": { + "domain": { + "type": "string" + }, + "retry": { + "type": "integer", + "format": "int64" + }, + "token": { + "type": "string" + } + } + }, + "endpoint": { + "type": "string" + }, + "tls": { + "type": "object", + "required": [ + "ca" + ], + "properties": { + "ca": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + } + } + } + } + }, + "GemaltoConfigurationResponseKeysecureCredentials": { + "type": "object", + "required": [ + "token", + "domain" + ], + "properties": { + "domain": { + "type": "string" + }, + "retry": { + "type": "integer", + "format": "int64" + }, + "token": { + "type": "string" + } + } + }, + "GemaltoConfigurationResponseKeysecureTLS": { + "type": "object", + "required": [ + "ca" + ], + "properties": { + "ca": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + } + } + }, "IdpConfigurationActiveDirectory": { "type": "object", "required": [ @@ -6003,6 +6383,50 @@ func init() { } } }, + "VaultConfigurationResponseApprole": { + "type": "object", + "required": [ + "id", + "secret" + ], + "properties": { + "engine": { + "type": "string" + }, + "id": { + "type": "string" + }, + "retry": { + "type": "integer", + "format": "int64" + }, + "secret": { + "type": "string" + } + } + }, + "VaultConfigurationResponseStatus": { + "type": "object", + "properties": { + "ping": { + "type": "integer", + "format": "int64" + } + } + }, + "VaultConfigurationResponseTLS": { + "type": "object", + "properties": { + "ca": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + }, + "crt": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + } + } + }, "VaultConfigurationStatus": { "type": "object", "properties": { @@ -6376,6 +6800,12 @@ func init() { "replicas": { "type": "string" }, + "secretsToBeDeleted": { + "type": "array", + "items": { + "type": "string" + } + }, "securityContext": { "type": "object", "$ref": "#/definitions/securityContext" @@ -6392,6 +6822,56 @@ func init() { } ] }, + "encryptionConfigurationResponse": { + "allOf": [ + { + "$ref": "#/definitions/metadataFields" + }, + { + "type": "object", + "properties": { + "aws": { + "type": "object", + "$ref": "#/definitions/awsConfiguration" + }, + "azure": { + "type": "object", + "$ref": "#/definitions/azureConfiguration" + }, + "gcp": { + "type": "object", + "$ref": "#/definitions/gcpConfiguration" + }, + "gemalto": { + "type": "object", + "$ref": "#/definitions/gemaltoConfigurationResponse" + }, + "image": { + "type": "string" + }, + "mtls_client": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + }, + "replicas": { + "type": "string" + }, + "securityContext": { + "type": "object", + "$ref": "#/definitions/securityContext" + }, + "server": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + }, + "vault": { + "type": "object", + "$ref": "#/definitions/vaultConfigurationResponse" + } + } + } + ] + }, "error": { "type": "object", "required": [ @@ -6560,6 +7040,57 @@ func init() { } } }, + "gemaltoConfigurationResponse": { + "type": "object", + "required": [ + "keysecure" + ], + "properties": { + "keysecure": { + "type": "object", + "required": [ + "endpoint", + "credentials" + ], + "properties": { + "credentials": { + "type": "object", + "required": [ + "token", + "domain" + ], + "properties": { + "domain": { + "type": "string" + }, + "retry": { + "type": "integer", + "format": "int64" + }, + "token": { + "type": "string" + } + } + }, + "endpoint": { + "type": "string" + }, + "tls": { + "type": "object", + "required": [ + "ca" + ], + "properties": { + "ca": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + } + } + } + } + } + } + }, "getDirectCSIDriveListResponse": { "type": "object", "properties": { @@ -7864,6 +8395,71 @@ func init() { } } } + }, + "vaultConfigurationResponse": { + "type": "object", + "required": [ + "endpoint", + "approle" + ], + "properties": { + "approle": { + "type": "object", + "required": [ + "id", + "secret" + ], + "properties": { + "engine": { + "type": "string" + }, + "id": { + "type": "string" + }, + "retry": { + "type": "integer", + "format": "int64" + }, + "secret": { + "type": "string" + } + } + }, + "endpoint": { + "type": "string" + }, + "engine": { + "type": "string" + }, + "namespace": { + "type": "string" + }, + "prefix": { + "type": "string" + }, + "status": { + "type": "object", + "properties": { + "ping": { + "type": "integer", + "format": "int64" + } + } + }, + "tls": { + "type": "object", + "properties": { + "ca": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + }, + "crt": { + "type": "object", + "$ref": "#/definitions/certificateInfo" + } + } + } + } } }, "securityDefinitions": { diff --git a/operatorapi/error.go b/operatorapi/error.go index cf3e89bbe..c3031cc60 100644 --- a/operatorapi/error.go +++ b/operatorapi/error.go @@ -42,6 +42,8 @@ var ( errorUnableToGetTenantLogs = errors.New("unable to get tenant logs") errorUnableToUpdateTenantCertificates = errors.New("unable to update tenant certificates") errorUpdatingEncryptionConfig = errors.New("unable to update encryption configuration") + errorDeletingEncryptionConfig = errors.New("error disabling tenant encryption") + errorEncryptionConfigNotFound = errors.New("encryption configuration not found") errBucketBodyNotInRequest = errors.New("error bucket body not in request") errBucketNameNotInRequest = errors.New("error bucket name not in request") errGroupBodyNotInRequest = errors.New("error group body not in request") diff --git a/operatorapi/operations/operator_api.go b/operatorapi/operations/operator_api.go index 4cfab922e..a7928f747 100644 --- a/operatorapi/operations/operator_api.go +++ b/operatorapi/operations/operator_api.go @@ -177,9 +177,15 @@ func NewOperatorAPI(spec *loads.Document) *OperatorAPI { OperatorAPITenantAddPoolHandler: operator_api.TenantAddPoolHandlerFunc(func(params operator_api.TenantAddPoolParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation operator_api.TenantAddPool has not yet been implemented") }), + OperatorAPITenantDeleteEncryptionHandler: operator_api.TenantDeleteEncryptionHandlerFunc(func(params operator_api.TenantDeleteEncryptionParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation operator_api.TenantDeleteEncryption has not yet been implemented") + }), OperatorAPITenantDetailsHandler: operator_api.TenantDetailsHandlerFunc(func(params operator_api.TenantDetailsParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation operator_api.TenantDetails has not yet been implemented") }), + OperatorAPITenantEncryptionInfoHandler: operator_api.TenantEncryptionInfoHandlerFunc(func(params operator_api.TenantEncryptionInfoParams, principal *models.Principal) middleware.Responder { + return middleware.NotImplemented("operation operator_api.TenantEncryptionInfo has not yet been implemented") + }), OperatorAPITenantSecurityHandler: operator_api.TenantSecurityHandlerFunc(func(params operator_api.TenantSecurityParams, principal *models.Principal) middleware.Responder { return middleware.NotImplemented("operation operator_api.TenantSecurity has not yet been implemented") }), @@ -323,8 +329,12 @@ type OperatorAPI struct { OperatorAPISubscriptionValidateHandler operator_api.SubscriptionValidateHandler // OperatorAPITenantAddPoolHandler sets the operation handler for the tenant add pool operation OperatorAPITenantAddPoolHandler operator_api.TenantAddPoolHandler + // OperatorAPITenantDeleteEncryptionHandler sets the operation handler for the tenant delete encryption operation + OperatorAPITenantDeleteEncryptionHandler operator_api.TenantDeleteEncryptionHandler // OperatorAPITenantDetailsHandler sets the operation handler for the tenant details operation OperatorAPITenantDetailsHandler operator_api.TenantDetailsHandler + // OperatorAPITenantEncryptionInfoHandler sets the operation handler for the tenant encryption info operation + OperatorAPITenantEncryptionInfoHandler operator_api.TenantEncryptionInfoHandler // OperatorAPITenantSecurityHandler sets the operation handler for the tenant security operation OperatorAPITenantSecurityHandler operator_api.TenantSecurityHandler // OperatorAPITenantUpdateCertificateHandler sets the operation handler for the tenant update certificate operation @@ -532,9 +542,15 @@ func (o *OperatorAPI) Validate() error { if o.OperatorAPITenantAddPoolHandler == nil { unregistered = append(unregistered, "operator_api.TenantAddPoolHandler") } + if o.OperatorAPITenantDeleteEncryptionHandler == nil { + unregistered = append(unregistered, "operator_api.TenantDeleteEncryptionHandler") + } if o.OperatorAPITenantDetailsHandler == nil { unregistered = append(unregistered, "operator_api.TenantDetailsHandler") } + if o.OperatorAPITenantEncryptionInfoHandler == nil { + unregistered = append(unregistered, "operator_api.TenantEncryptionInfoHandler") + } if o.OperatorAPITenantSecurityHandler == nil { unregistered = append(unregistered, "operator_api.TenantSecurityHandler") } @@ -803,6 +819,10 @@ func (o *OperatorAPI) initHandlerCache() { o.handlers["POST"] = make(map[string]http.Handler) } o.handlers["POST"]["/namespaces/{namespace}/tenants/{tenant}/pools"] = operator_api.NewTenantAddPool(o.context, o.OperatorAPITenantAddPoolHandler) + if o.handlers["DELETE"] == nil { + o.handlers["DELETE"] = make(map[string]http.Handler) + } + o.handlers["DELETE"]["/namespaces/{namespace}/tenants/{tenant}/encryption"] = operator_api.NewTenantDeleteEncryption(o.context, o.OperatorAPITenantDeleteEncryptionHandler) if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } @@ -810,6 +830,10 @@ func (o *OperatorAPI) initHandlerCache() { if o.handlers["GET"] == nil { o.handlers["GET"] = make(map[string]http.Handler) } + o.handlers["GET"]["/namespaces/{namespace}/tenants/{tenant}/encryption"] = operator_api.NewTenantEncryptionInfo(o.context, o.OperatorAPITenantEncryptionInfoHandler) + if o.handlers["GET"] == nil { + o.handlers["GET"] = make(map[string]http.Handler) + } o.handlers["GET"]["/namespaces/{namespace}/tenants/{tenant}/security"] = operator_api.NewTenantSecurity(o.context, o.OperatorAPITenantSecurityHandler) if o.handlers["PUT"] == nil { o.handlers["PUT"] = make(map[string]http.Handler) diff --git a/operatorapi/operations/operator_api/tenant_delete_encryption.go b/operatorapi/operations/operator_api/tenant_delete_encryption.go new file mode 100644 index 000000000..aa8c54b01 --- /dev/null +++ b/operatorapi/operations/operator_api/tenant_delete_encryption.go @@ -0,0 +1,88 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package operator_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// TenantDeleteEncryptionHandlerFunc turns a function with the right signature into a tenant delete encryption handler +type TenantDeleteEncryptionHandlerFunc func(TenantDeleteEncryptionParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn TenantDeleteEncryptionHandlerFunc) Handle(params TenantDeleteEncryptionParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// TenantDeleteEncryptionHandler interface for that can handle valid tenant delete encryption params +type TenantDeleteEncryptionHandler interface { + Handle(TenantDeleteEncryptionParams, *models.Principal) middleware.Responder +} + +// NewTenantDeleteEncryption creates a new http.Handler for the tenant delete encryption operation +func NewTenantDeleteEncryption(ctx *middleware.Context, handler TenantDeleteEncryptionHandler) *TenantDeleteEncryption { + return &TenantDeleteEncryption{Context: ctx, Handler: handler} +} + +/* TenantDeleteEncryption swagger:route DELETE /namespaces/{namespace}/tenants/{tenant}/encryption OperatorAPI tenantDeleteEncryption + +Tenant Delete Encryption + +*/ +type TenantDeleteEncryption struct { + Context *middleware.Context + Handler TenantDeleteEncryptionHandler +} + +func (o *TenantDeleteEncryption) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewTenantDeleteEncryptionParams() + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + *r = *aCtx + } + var principal *models.Principal + if uprinc != nil { + principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/operatorapi/operations/operator_api/tenant_delete_encryption_parameters.go b/operatorapi/operations/operator_api/tenant_delete_encryption_parameters.go new file mode 100644 index 000000000..cbf3fa147 --- /dev/null +++ b/operatorapi/operations/operator_api/tenant_delete_encryption_parameters.go @@ -0,0 +1,112 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package operator_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" +) + +// NewTenantDeleteEncryptionParams creates a new TenantDeleteEncryptionParams object +// +// There are no default values defined in the spec. +func NewTenantDeleteEncryptionParams() TenantDeleteEncryptionParams { + + return TenantDeleteEncryptionParams{} +} + +// TenantDeleteEncryptionParams contains all the bound params for the tenant delete encryption operation +// typically these are obtained from a http.Request +// +// swagger:parameters TenantDeleteEncryption +type TenantDeleteEncryptionParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: path + */ + Namespace string + /* + Required: true + In: path + */ + Tenant string +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewTenantDeleteEncryptionParams() beforehand. +func (o *TenantDeleteEncryptionParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + rNamespace, rhkNamespace, _ := route.Params.GetOK("namespace") + if err := o.bindNamespace(rNamespace, rhkNamespace, route.Formats); err != nil { + res = append(res, err) + } + + rTenant, rhkTenant, _ := route.Params.GetOK("tenant") + if err := o.bindTenant(rTenant, rhkTenant, route.Formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindNamespace binds and validates parameter Namespace from path. +func (o *TenantDeleteEncryptionParams) bindNamespace(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + o.Namespace = raw + + return nil +} + +// bindTenant binds and validates parameter Tenant from path. +func (o *TenantDeleteEncryptionParams) bindTenant(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + o.Tenant = raw + + return nil +} diff --git a/operatorapi/operations/operator_api/tenant_delete_encryption_responses.go b/operatorapi/operations/operator_api/tenant_delete_encryption_responses.go new file mode 100644 index 000000000..ec80d5af3 --- /dev/null +++ b/operatorapi/operations/operator_api/tenant_delete_encryption_responses.go @@ -0,0 +1,113 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package operator_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/minio/console/models" +) + +// TenantDeleteEncryptionNoContentCode is the HTTP code returned for type TenantDeleteEncryptionNoContent +const TenantDeleteEncryptionNoContentCode int = 204 + +/*TenantDeleteEncryptionNoContent A successful response. + +swagger:response tenantDeleteEncryptionNoContent +*/ +type TenantDeleteEncryptionNoContent struct { +} + +// NewTenantDeleteEncryptionNoContent creates TenantDeleteEncryptionNoContent with default headers values +func NewTenantDeleteEncryptionNoContent() *TenantDeleteEncryptionNoContent { + + return &TenantDeleteEncryptionNoContent{} +} + +// WriteResponse to the client +func (o *TenantDeleteEncryptionNoContent) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.Header().Del(runtime.HeaderContentType) //Remove Content-Type on empty responses + + rw.WriteHeader(204) +} + +/*TenantDeleteEncryptionDefault Generic error response. + +swagger:response tenantDeleteEncryptionDefault +*/ +type TenantDeleteEncryptionDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewTenantDeleteEncryptionDefault creates TenantDeleteEncryptionDefault with default headers values +func NewTenantDeleteEncryptionDefault(code int) *TenantDeleteEncryptionDefault { + if code <= 0 { + code = 500 + } + + return &TenantDeleteEncryptionDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the tenant delete encryption default response +func (o *TenantDeleteEncryptionDefault) WithStatusCode(code int) *TenantDeleteEncryptionDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the tenant delete encryption default response +func (o *TenantDeleteEncryptionDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the tenant delete encryption default response +func (o *TenantDeleteEncryptionDefault) WithPayload(payload *models.Error) *TenantDeleteEncryptionDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the tenant delete encryption default response +func (o *TenantDeleteEncryptionDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *TenantDeleteEncryptionDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/operatorapi/operations/operator_api/tenant_delete_encryption_urlbuilder.go b/operatorapi/operations/operator_api/tenant_delete_encryption_urlbuilder.go new file mode 100644 index 000000000..c23967d70 --- /dev/null +++ b/operatorapi/operations/operator_api/tenant_delete_encryption_urlbuilder.go @@ -0,0 +1,124 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package operator_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" +) + +// TenantDeleteEncryptionURL generates an URL for the tenant delete encryption operation +type TenantDeleteEncryptionURL struct { + Namespace string + Tenant string + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *TenantDeleteEncryptionURL) WithBasePath(bp string) *TenantDeleteEncryptionURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *TenantDeleteEncryptionURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *TenantDeleteEncryptionURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/namespaces/{namespace}/tenants/{tenant}/encryption" + + namespace := o.Namespace + if namespace != "" { + _path = strings.Replace(_path, "{namespace}", namespace, -1) + } else { + return nil, errors.New("namespace is required on TenantDeleteEncryptionURL") + } + + tenant := o.Tenant + if tenant != "" { + _path = strings.Replace(_path, "{tenant}", tenant, -1) + } else { + return nil, errors.New("tenant is required on TenantDeleteEncryptionURL") + } + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *TenantDeleteEncryptionURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *TenantDeleteEncryptionURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *TenantDeleteEncryptionURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on TenantDeleteEncryptionURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on TenantDeleteEncryptionURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *TenantDeleteEncryptionURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/operatorapi/operations/operator_api/tenant_encryption_info.go b/operatorapi/operations/operator_api/tenant_encryption_info.go new file mode 100644 index 000000000..b46f32cf8 --- /dev/null +++ b/operatorapi/operations/operator_api/tenant_encryption_info.go @@ -0,0 +1,88 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package operator_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime/middleware" + + "github.com/minio/console/models" +) + +// TenantEncryptionInfoHandlerFunc turns a function with the right signature into a tenant encryption info handler +type TenantEncryptionInfoHandlerFunc func(TenantEncryptionInfoParams, *models.Principal) middleware.Responder + +// Handle executing the request and returning a response +func (fn TenantEncryptionInfoHandlerFunc) Handle(params TenantEncryptionInfoParams, principal *models.Principal) middleware.Responder { + return fn(params, principal) +} + +// TenantEncryptionInfoHandler interface for that can handle valid tenant encryption info params +type TenantEncryptionInfoHandler interface { + Handle(TenantEncryptionInfoParams, *models.Principal) middleware.Responder +} + +// NewTenantEncryptionInfo creates a new http.Handler for the tenant encryption info operation +func NewTenantEncryptionInfo(ctx *middleware.Context, handler TenantEncryptionInfoHandler) *TenantEncryptionInfo { + return &TenantEncryptionInfo{Context: ctx, Handler: handler} +} + +/* TenantEncryptionInfo swagger:route GET /namespaces/{namespace}/tenants/{tenant}/encryption OperatorAPI tenantEncryptionInfo + +Tenant Encryption Info + +*/ +type TenantEncryptionInfo struct { + Context *middleware.Context + Handler TenantEncryptionInfoHandler +} + +func (o *TenantEncryptionInfo) ServeHTTP(rw http.ResponseWriter, r *http.Request) { + route, rCtx, _ := o.Context.RouteInfo(r) + if rCtx != nil { + *r = *rCtx + } + var Params = NewTenantEncryptionInfoParams() + uprinc, aCtx, err := o.Context.Authorize(r, route) + if err != nil { + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + if aCtx != nil { + *r = *aCtx + } + var principal *models.Principal + if uprinc != nil { + principal = uprinc.(*models.Principal) // this is really a models.Principal, I promise + } + + if err := o.Context.BindValidRequest(r, route, &Params); err != nil { // bind params + o.Context.Respond(rw, r, route.Produces, route, err) + return + } + + res := o.Handler.Handle(Params, principal) // actually handle the request + o.Context.Respond(rw, r, route.Produces, route, res) + +} diff --git a/operatorapi/operations/operator_api/tenant_encryption_info_parameters.go b/operatorapi/operations/operator_api/tenant_encryption_info_parameters.go new file mode 100644 index 000000000..284379089 --- /dev/null +++ b/operatorapi/operations/operator_api/tenant_encryption_info_parameters.go @@ -0,0 +1,112 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package operator_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/errors" + "github.com/go-openapi/runtime/middleware" + "github.com/go-openapi/strfmt" +) + +// NewTenantEncryptionInfoParams creates a new TenantEncryptionInfoParams object +// +// There are no default values defined in the spec. +func NewTenantEncryptionInfoParams() TenantEncryptionInfoParams { + + return TenantEncryptionInfoParams{} +} + +// TenantEncryptionInfoParams contains all the bound params for the tenant encryption info operation +// typically these are obtained from a http.Request +// +// swagger:parameters TenantEncryptionInfo +type TenantEncryptionInfoParams struct { + + // HTTP Request Object + HTTPRequest *http.Request `json:"-"` + + /* + Required: true + In: path + */ + Namespace string + /* + Required: true + In: path + */ + Tenant string +} + +// BindRequest both binds and validates a request, it assumes that complex things implement a Validatable(strfmt.Registry) error interface +// for simple values it will use straight method calls. +// +// To ensure default values, the struct must have been initialized with NewTenantEncryptionInfoParams() beforehand. +func (o *TenantEncryptionInfoParams) BindRequest(r *http.Request, route *middleware.MatchedRoute) error { + var res []error + + o.HTTPRequest = r + + rNamespace, rhkNamespace, _ := route.Params.GetOK("namespace") + if err := o.bindNamespace(rNamespace, rhkNamespace, route.Formats); err != nil { + res = append(res, err) + } + + rTenant, rhkTenant, _ := route.Params.GetOK("tenant") + if err := o.bindTenant(rTenant, rhkTenant, route.Formats); err != nil { + res = append(res, err) + } + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +// bindNamespace binds and validates parameter Namespace from path. +func (o *TenantEncryptionInfoParams) bindNamespace(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + o.Namespace = raw + + return nil +} + +// bindTenant binds and validates parameter Tenant from path. +func (o *TenantEncryptionInfoParams) bindTenant(rawData []string, hasKey bool, formats strfmt.Registry) error { + var raw string + if len(rawData) > 0 { + raw = rawData[len(rawData)-1] + } + + // Required: true + // Parameter is provided by construction from the route + o.Tenant = raw + + return nil +} diff --git a/operatorapi/operations/operator_api/tenant_encryption_info_responses.go b/operatorapi/operations/operator_api/tenant_encryption_info_responses.go new file mode 100644 index 000000000..97df97dee --- /dev/null +++ b/operatorapi/operations/operator_api/tenant_encryption_info_responses.go @@ -0,0 +1,133 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package operator_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the swagger generate command + +import ( + "net/http" + + "github.com/go-openapi/runtime" + + "github.com/minio/console/models" +) + +// TenantEncryptionInfoOKCode is the HTTP code returned for type TenantEncryptionInfoOK +const TenantEncryptionInfoOKCode int = 200 + +/*TenantEncryptionInfoOK A successful response. + +swagger:response tenantEncryptionInfoOK +*/ +type TenantEncryptionInfoOK struct { + + /* + In: Body + */ + Payload *models.EncryptionConfigurationResponse `json:"body,omitempty"` +} + +// NewTenantEncryptionInfoOK creates TenantEncryptionInfoOK with default headers values +func NewTenantEncryptionInfoOK() *TenantEncryptionInfoOK { + + return &TenantEncryptionInfoOK{} +} + +// WithPayload adds the payload to the tenant encryption info o k response +func (o *TenantEncryptionInfoOK) WithPayload(payload *models.EncryptionConfigurationResponse) *TenantEncryptionInfoOK { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the tenant encryption info o k response +func (o *TenantEncryptionInfoOK) SetPayload(payload *models.EncryptionConfigurationResponse) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *TenantEncryptionInfoOK) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(200) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} + +/*TenantEncryptionInfoDefault Generic error response. + +swagger:response tenantEncryptionInfoDefault +*/ +type TenantEncryptionInfoDefault struct { + _statusCode int + + /* + In: Body + */ + Payload *models.Error `json:"body,omitempty"` +} + +// NewTenantEncryptionInfoDefault creates TenantEncryptionInfoDefault with default headers values +func NewTenantEncryptionInfoDefault(code int) *TenantEncryptionInfoDefault { + if code <= 0 { + code = 500 + } + + return &TenantEncryptionInfoDefault{ + _statusCode: code, + } +} + +// WithStatusCode adds the status to the tenant encryption info default response +func (o *TenantEncryptionInfoDefault) WithStatusCode(code int) *TenantEncryptionInfoDefault { + o._statusCode = code + return o +} + +// SetStatusCode sets the status to the tenant encryption info default response +func (o *TenantEncryptionInfoDefault) SetStatusCode(code int) { + o._statusCode = code +} + +// WithPayload adds the payload to the tenant encryption info default response +func (o *TenantEncryptionInfoDefault) WithPayload(payload *models.Error) *TenantEncryptionInfoDefault { + o.Payload = payload + return o +} + +// SetPayload sets the payload to the tenant encryption info default response +func (o *TenantEncryptionInfoDefault) SetPayload(payload *models.Error) { + o.Payload = payload +} + +// WriteResponse to the client +func (o *TenantEncryptionInfoDefault) WriteResponse(rw http.ResponseWriter, producer runtime.Producer) { + + rw.WriteHeader(o._statusCode) + if o.Payload != nil { + payload := o.Payload + if err := producer.Produce(rw, payload); err != nil { + panic(err) // let the recovery middleware deal with this + } + } +} diff --git a/operatorapi/operations/operator_api/tenant_encryption_info_urlbuilder.go b/operatorapi/operations/operator_api/tenant_encryption_info_urlbuilder.go new file mode 100644 index 000000000..26167cd1f --- /dev/null +++ b/operatorapi/operations/operator_api/tenant_encryption_info_urlbuilder.go @@ -0,0 +1,124 @@ +// Code generated by go-swagger; DO NOT EDIT. + +// This file is part of MinIO Console Server +// Copyright (c) 2021 MinIO, Inc. +// +// This program is free software: you can redistribute it and/or modify +// it under the terms of the GNU Affero General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU Affero General Public License for more details. +// +// You should have received a copy of the GNU Affero General Public License +// along with this program. If not, see . +// + +package operator_api + +// This file was generated by the swagger tool. +// Editing this file might prove futile when you re-run the generate command + +import ( + "errors" + "net/url" + golangswaggerpaths "path" + "strings" +) + +// TenantEncryptionInfoURL generates an URL for the tenant encryption info operation +type TenantEncryptionInfoURL struct { + Namespace string + Tenant string + + _basePath string + // avoid unkeyed usage + _ struct{} +} + +// WithBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *TenantEncryptionInfoURL) WithBasePath(bp string) *TenantEncryptionInfoURL { + o.SetBasePath(bp) + return o +} + +// SetBasePath sets the base path for this url builder, only required when it's different from the +// base path specified in the swagger spec. +// When the value of the base path is an empty string +func (o *TenantEncryptionInfoURL) SetBasePath(bp string) { + o._basePath = bp +} + +// Build a url path and query string +func (o *TenantEncryptionInfoURL) Build() (*url.URL, error) { + var _result url.URL + + var _path = "/namespaces/{namespace}/tenants/{tenant}/encryption" + + namespace := o.Namespace + if namespace != "" { + _path = strings.Replace(_path, "{namespace}", namespace, -1) + } else { + return nil, errors.New("namespace is required on TenantEncryptionInfoURL") + } + + tenant := o.Tenant + if tenant != "" { + _path = strings.Replace(_path, "{tenant}", tenant, -1) + } else { + return nil, errors.New("tenant is required on TenantEncryptionInfoURL") + } + + _basePath := o._basePath + if _basePath == "" { + _basePath = "/api/v1" + } + _result.Path = golangswaggerpaths.Join(_basePath, _path) + + return &_result, nil +} + +// Must is a helper function to panic when the url builder returns an error +func (o *TenantEncryptionInfoURL) Must(u *url.URL, err error) *url.URL { + if err != nil { + panic(err) + } + if u == nil { + panic("url can't be nil") + } + return u +} + +// String returns the string representation of the path with query string +func (o *TenantEncryptionInfoURL) String() string { + return o.Must(o.Build()).String() +} + +// BuildFull builds a full url with scheme, host, path and query string +func (o *TenantEncryptionInfoURL) BuildFull(scheme, host string) (*url.URL, error) { + if scheme == "" { + return nil, errors.New("scheme is required for a full url on TenantEncryptionInfoURL") + } + if host == "" { + return nil, errors.New("host is required for a full url on TenantEncryptionInfoURL") + } + + base, err := o.Build() + if err != nil { + return nil, err + } + + base.Scheme = scheme + base.Host = host + return base, nil +} + +// StringFull returns the string representation of a complete url +func (o *TenantEncryptionInfoURL) StringFull(scheme, host string) string { + return o.Must(o.BuildFull(scheme, host)).String() +} diff --git a/operatorapi/operator_tenants.go b/operatorapi/operator_tenants.go index 499e6fd89..21f991f61 100644 --- a/operatorapi/operator_tenants.go +++ b/operatorapi/operator_tenants.go @@ -280,6 +280,24 @@ func registerTenantHandlers(api *operations.OperatorAPI) { return operator_api.NewTenantUpdateEncryptionCreated() }) + // Delete tenant Encryption Configuration + api.OperatorAPITenantDeleteEncryptionHandler = operator_api.TenantDeleteEncryptionHandlerFunc(func(params operator_api.TenantDeleteEncryptionParams, session *models.Principal) middleware.Responder { + err := getTenantDeleteEncryptionResponse(session, params) + if err != nil { + return operator_api.NewTenantDeleteEncryptionDefault(int(err.Code)).WithPayload(err) + } + return operator_api.NewTenantDeleteEncryptionNoContent() + }) + + // Get Tenant Encryption Configuration + api.OperatorAPITenantEncryptionInfoHandler = operator_api.TenantEncryptionInfoHandlerFunc(func(params operator_api.TenantEncryptionInfoParams, session *models.Principal) middleware.Responder { + configuration, err := getTenantEncryptionInfoResponse(session, params) + if err != nil { + return operator_api.NewTenantEncryptionInfoDefault(int(err.Code)).WithPayload(err) + } + return operator_api.NewTenantEncryptionInfoOK().WithPayload(configuration) + }) + // Get Tenant YAML api.OperatorAPIGetTenantYAMLHandler = operator_api.GetTenantYAMLHandlerFunc(func(params operator_api.GetTenantYAMLParams, principal *models.Principal) middleware.Responder { payload, err := getTenantYAML(principal, params) @@ -635,6 +653,34 @@ func getTenantDetailsResponse(session *models.Principal, params operator_api.Ten return info, nil } +func parseCertificate(name string, rawCert []byte) (*models.CertificateInfo, error) { + block, _ := pem.Decode(rawCert) + if block == nil { + return nil, errors.New("certificate failed to decode") + } + cert, err := x509.ParseCertificate(block.Bytes) + if err != nil { + return nil, err + } + domains := []string{} + // 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()) + } + } + return &models.CertificateInfo{ + SerialNumber: cert.SerialNumber.String(), + Name: name, + Domains: domains, + Expiry: cert.NotAfter.String(), + }, nil +} + // parseTenantCertificates convert public key pem certificates stored in k8s secrets for a given Tenant into x509 certificates func parseTenantCertificates(ctx context.Context, clientSet K8sClientI, namespace string, secrets []*miniov2.LocalCertificateReference) ([]*models.CertificateInfo, error) { var certificates []*models.CertificateInfo @@ -1207,7 +1253,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre minInst.Spec.KES.NodeSelector = tenantReq.Encryption.NodeSelector if tenantReq.Encryption.SecurityContext != nil { - sc, err := parseSecurityContext(tenantReq.Encryption.SecurityContext) + sc, err := convertModelSCToK8sSC(tenantReq.Encryption.SecurityContext) if err != nil { return nil, prepareError(err) } @@ -1309,7 +1355,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre } // if security context for logSearch is present, configure it. if tenantReq.LogSearchConfiguration.SecurityContext != nil { - sc, err := parseSecurityContext(tenantReq.LogSearchConfiguration.SecurityContext) + sc, err := convertModelSCToK8sSC(tenantReq.LogSearchConfiguration.SecurityContext) if err != nil { return nil, prepareError(err) } @@ -1317,7 +1363,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre } // if security context for logSearch is present, configure it. if tenantReq.LogSearchConfiguration.PostgresSecurityContext != nil { - sc, err := parseSecurityContext(tenantReq.LogSearchConfiguration.PostgresSecurityContext) + sc, err := convertModelSCToK8sSC(tenantReq.LogSearchConfiguration.PostgresSecurityContext) if err != nil { return nil, prepareError(err) } @@ -1411,7 +1457,7 @@ func getTenantCreatedResponse(session *models.Principal, params operator_api.Cre } // if security context for prometheus is present, configure it. if tenantReq.PrometheusConfiguration != nil && tenantReq.PrometheusConfiguration.SecurityContext != nil { - sc, err := parseSecurityContext(tenantReq.PrometheusConfiguration.SecurityContext) + sc, err := convertModelSCToK8sSC(tenantReq.PrometheusConfiguration.SecurityContext) if err != nil { return nil, prepareError(err) } @@ -2550,7 +2596,7 @@ func parseTenantPoolRequest(poolParams *models.Pool) (*miniov2.Pool, error) { } // if security context for Tenant is present, configure it. if poolParams.SecurityContext != nil { - sc, err := parseSecurityContext(poolParams.SecurityContext) + sc, err := convertModelSCToK8sSC(poolParams.SecurityContext) if err != nil { return nil, err } diff --git a/operatorapi/operator_tenants_helper.go b/operatorapi/operator_tenants_helper.go index 77fb592f3..6fc08dcff 100644 --- a/operatorapi/operator_tenants_helper.go +++ b/operatorapi/operator_tenants_helper.go @@ -22,6 +22,7 @@ import ( "crypto/tls" "encoding/base64" "encoding/hex" + "encoding/json" "fmt" "strconv" "time" @@ -39,8 +40,8 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// parseSecurityContext validate and return securityContext for pods -func parseSecurityContext(sc *models.SecurityContext) (*corev1.PodSecurityContext, error) { +// convertModelSCToK8sSC validates and converts from models.SecurityContext to corev1.PodSecurityContext +func convertModelSCToK8sSC(sc *models.SecurityContext) (*corev1.PodSecurityContext, error) { if sc == nil { return nil, errors.New("invalid security context") } @@ -64,6 +65,19 @@ func parseSecurityContext(sc *models.SecurityContext) (*corev1.PodSecurityContex }, nil } +// convertK8sSCToModelSC validates and converts from corev1.PodSecurityContext to models.SecurityContext +func convertK8sSCToModelSC(sc *corev1.PodSecurityContext) *models.SecurityContext { + runAsUser := strconv.FormatInt(*sc.RunAsUser, 10) + RunAsGroup := strconv.FormatInt(*sc.RunAsGroup, 10) + FsGroup := strconv.FormatInt(*sc.FSGroup, 10) + return &models.SecurityContext{ + RunAsUser: &runAsUser, + RunAsGroup: &RunAsGroup, + RunAsNonRoot: sc.RunAsNonRoot, + FsGroup: &FsGroup, + } +} + // tenantUpdateCertificates receives the keyPair certificates (public and private keys) for Minio and Console and will try // to replace the existing kubernetes secrets with the new values, then will restart the affected pods so the new volumes can be mounted func tenantUpdateCertificates(ctx context.Context, operatorClient OperatorClientI, clientSet K8sClientI, namespace string, params operator_api.TenantUpdateCertificateParams) error { @@ -116,6 +130,22 @@ func getTenantUpdateCertificatesResponse(session *models.Principal, params opera return nil } +// tenantDeleteEncryption allow user to disable tenant encryption for a particular tenant +func tenantDeleteEncryption(ctx context.Context, operatorClient OperatorClientI, namespace string, params operator_api.TenantDeleteEncryptionParams) error { + tenantName := params.Tenant + tenant, err := operatorClient.TenantGet(ctx, namespace, tenantName, metav1.GetOptions{}) + if err != nil { + return err + } + tenant.EnsureDefaults() + tenant.Spec.KES = nil + _, err = operatorClient.TenantUpdate(ctx, tenant, metav1.UpdateOptions{}) + if err != nil { + return err + } + return nil +} + // tenantUpdateEncryption allow user to update KES server certificates, KES client certificates (used by MinIO for mTLS) and KES configuration (KMS configuration, credentials, etc) func tenantUpdateEncryption(ctx context.Context, operatorClient OperatorClientI, clientSet K8sClientI, namespace string, params operator_api.TenantUpdateEncryptionParams) error { tenantName := params.Tenant @@ -125,47 +155,99 @@ func tenantUpdateEncryption(ctx context.Context, operatorClient OperatorClientI, if err != nil { return err } - // Check if encryption is enabled for MinIO via KES - if tenant.HasKESEnabled() { - // check if KES is deployed with external certificates and user provided new server keypair - if tenant.KESExternalCert() && body.Server != nil { - kesExternalCertSecretName := fmt.Sprintf("%s-kes-external-cert", secretName) - // update certificates - certificates := []*models.KeyPairConfiguration{body.Server} - if _, err := createOrReplaceExternalCertSecrets(ctx, clientSet, namespace, certificates, kesExternalCertSecretName, tenantName); err != nil { - return err + tenant.EnsureDefaults() + // Initialize KES configuration if not present + if !tenant.HasKESEnabled() { + tenant.Spec.KES = &miniov2.KESConfig{} + } + if tenant.KESExternalCert() { + for _, certificateToBeDeleted := range params.Body.SecretsToBeDeleted { + if tenant.Spec.KES.ExternalCertSecret.Name == certificateToBeDeleted { + tenant.Spec.KES.ExternalCertSecret = nil + break } } - // check if Tenant is deployed with external client certificates and user provided new client keypaiir - if tenant.ExternalClientCert() && body.Client != nil { - tenantExternalClientCertSecretName := fmt.Sprintf("%s-tenant-external-client-cert", secretName) - // Update certificates - certificates := []*models.KeyPairConfiguration{body.Client} - if _, err := createOrReplaceExternalCertSecrets(ctx, clientSet, namespace, certificates, tenantExternalClientCertSecretName, tenantName); err != nil { - return err - } - // Restart MinIO pods to mount the new client secrets - err := clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", miniov2.TenantLabel, tenantName), - }) - if err != nil { - return err + } + if tenant.ExternalClientCert() { + for _, certificateToBeDeleted := range params.Body.SecretsToBeDeleted { + if tenant.Spec.ExternalClientCertSecret.Name == certificateToBeDeleted { + tenant.Spec.ExternalClientCertSecret = nil + break } } - // update KES identities in kes-configuration.yaml secret - kesConfigurationSecretName := fmt.Sprintf("%s-kes-configuration", secretName) - kesClientCertSecretName := fmt.Sprintf("%s-kes-client-cert", secretName) - _, _, err := createOrReplaceKesConfigurationSecrets(ctx, clientSet, namespace, body, kesConfigurationSecretName, kesClientCertSecretName, tenantName) + } + if body.Server != nil { + kesExternalCertSecretName := fmt.Sprintf("%s-kes-external-cert", secretName) + if tenant.KESExternalCert() { + kesExternalCertSecretName = tenant.Spec.KES.ExternalCertSecret.Name + } + // update certificates + certificates := []*models.KeyPairConfiguration{body.Server} + createdCertificates, err := createOrReplaceExternalCertSecrets(ctx, clientSet, namespace, certificates, kesExternalCertSecretName, tenantName) if err != nil { return err } - // Restart KES pods to mount the new configuration - err = clientSet.deletePodCollection(ctx, namespace, metav1.DeleteOptions{}, metav1.ListOptions{ - LabelSelector: fmt.Sprintf("%s=%s", miniov2.KESInstanceLabel, fmt.Sprintf("%s-kes", tenantName)), - }) + if len(createdCertificates) > 0 { + tenant.Spec.KES.ExternalCertSecret = createdCertificates[0] + } + } + if body.Client != nil { + tenantExternalClientCertSecretName := fmt.Sprintf("%s-tenant-external-client-cert", secretName) + if tenant.ExternalClientCert() { + tenantExternalClientCertSecretName = tenant.Spec.ExternalClientCertSecret.Name + } + // Update certificates + certificates := []*models.KeyPairConfiguration{body.Client} + createdCertificates, err := createOrReplaceExternalCertSecrets(ctx, clientSet, namespace, certificates, tenantExternalClientCertSecretName, tenantName) if err != nil { return err } + if len(createdCertificates) > 0 { + tenant.Spec.ExternalClientCertSecret = createdCertificates[0] + } + } + // update KES identities in kes-configuration.yaml secret + kesConfigurationSecretName := fmt.Sprintf("%s-kes-configuration", secretName) + kesClientCertSecretName := fmt.Sprintf("%s-kes-client-cert", secretName) + kesConfigurationSecret, kesClientCertSecret, err := createOrReplaceKesConfigurationSecrets(ctx, clientSet, namespace, body, kesConfigurationSecretName, kesClientCertSecretName, tenantName) + if err != nil { + return err + } + tenant.Spec.KES.Configuration = kesConfigurationSecret + tenant.Spec.KES.ClientCertSecret = kesClientCertSecret + image := params.Body.Image + if image == "" { + image = miniov2.DefaultKESImage + } + tenant.Spec.KES.Image = image + i, err := strconv.ParseInt(params.Body.Replicas, 10, 32) + if err != nil { + return err + } + tenant.Spec.KES.Replicas = int32(i) + tenant.Spec.KES.SecurityContext, err = convertModelSCToK8sSC(params.Body.SecurityContext) + if err != nil { + return err + } + _, err = operatorClient.TenantUpdate(ctx, tenant, metav1.UpdateOptions{}) + if err != nil { + return err + } + return nil +} + +// getTenantDeleteEncryptionResponse is a wrapper for tenantDeleteEncryption +func getTenantDeleteEncryptionResponse(session *models.Principal, params operator_api.TenantDeleteEncryptionParams) *models.Error { + ctx := context.Background() + opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken) + if err != nil { + return prepareError(err, errorDeletingEncryptionConfig) + } + opClient := operatorClient{ + client: opClientClientSet, + } + if err := tenantDeleteEncryption(ctx, &opClient, params.Namespace, params); err != nil { + return prepareError(err, errorDeletingEncryptionConfig) } return nil } @@ -194,6 +276,203 @@ func getTenantUpdateEncryptionResponse(session *models.Principal, params operato return nil } +// tenantEncryptionInfo retrieves encryption information for the current tenant +func tenantEncryptionInfo(ctx context.Context, operatorClient OperatorClientI, clientSet K8sClientI, namespace string, params operator_api.TenantEncryptionInfoParams) (*models.EncryptionConfigurationResponse, error) { + tenantName := params.Tenant + tenant, err := operatorClient.TenantGet(ctx, namespace, tenantName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + // Check if encryption is enabled for MinIO via KES + if tenant.HasKESEnabled() { + encryptConfig := &models.EncryptionConfigurationResponse{ + Image: tenant.Spec.KES.Image, + Replicas: fmt.Sprintf("%d", tenant.Spec.KES.Replicas), + } + if tenant.Spec.KES.Image == "" { + encryptConfig.Image = miniov2.GetTenantKesImage() + } + if tenant.Spec.KES.SecurityContext != nil { + encryptConfig.SecurityContext = convertK8sSCToModelSC(tenant.Spec.KES.SecurityContext) + } + if tenant.KESExternalCert() { + kesExternalCerts, err := parseTenantCertificates(ctx, clientSet, tenant.Namespace, []*miniov2.LocalCertificateReference{tenant.Spec.KES.ExternalCertSecret}) + if err != nil { + return nil, err + } + if len(kesExternalCerts) > 0 { + encryptConfig.Server = kesExternalCerts[0] + } + } + if tenant.ExternalClientCert() { + clientCerts, err := parseTenantCertificates(ctx, clientSet, tenant.Namespace, []*miniov2.LocalCertificateReference{tenant.Spec.ExternalClientCertSecret}) + if err != nil { + return nil, err + } + if len(clientCerts) > 0 { + encryptConfig.MtlsClient = clientCerts[0] + } + } + + if tenant.Spec.KES.Configuration != nil { + configSecret, err := clientSet.getSecret(ctx, tenant.Namespace, tenant.Spec.KES.Configuration.Name, metav1.GetOptions{}) + if err != nil { + return nil, err + } + if rawConfiguration, ok := configSecret.Data["server-config.yaml"]; ok { + kesConfiguration := &kes.ServerConfig{} + err := yaml.Unmarshal(rawConfiguration, kesConfiguration) + if err != nil { + return nil, err + } + if kesConfiguration.Keys.Vault != nil { + vault := kesConfiguration.Keys.Vault + vaultConfig := &models.VaultConfigurationResponse{ + Prefix: vault.Prefix, + Namespace: vault.Namespace, + Engine: vault.EnginePath, + Endpoint: &vault.Endpoint, + } + if vault.Status != nil { + vaultConfig.Status = &models.VaultConfigurationResponseStatus{ + Ping: int64(vault.Status.Ping.Seconds()), + } + } + if vault.AppRole != nil { + vaultConfig.Approle = &models.VaultConfigurationResponseApprole{ + Engine: vault.AppRole.EnginePath, + ID: &vault.AppRole.ID, + Retry: int64(vault.AppRole.Retry.Seconds()), + Secret: &vault.AppRole.Secret, + } + } + if tenant.KESClientCert() { + vaultConfig.TLS = &models.VaultConfigurationResponseTLS{} + clientSecretName := tenant.Spec.KES.ClientCertSecret.Name + keyPair, err := clientSet.getSecret(ctx, namespace, clientSecretName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + // Extract client public certificate + if rawCert, ok := keyPair.Data["client.crt"]; ok { + vaultConfig.TLS.Crt, err = parseCertificate(clientSecretName, rawCert) + if err != nil { + return nil, err + } + } + // Extract client ca certificate + if rawCert, ok := keyPair.Data["ca.crt"]; ok { + vaultConfig.TLS.Ca, err = parseCertificate(clientSecretName, rawCert) + if err != nil { + return nil, err + } + } + } + encryptConfig.Vault = vaultConfig + } + if kesConfiguration.Keys.Aws != nil { + awsJSON, err := json.Marshal(kesConfiguration.Keys.Aws) + if err != nil { + return nil, err + } + awsConfig := &models.AwsConfiguration{} + err = json.Unmarshal(awsJSON, awsConfig) + if err != nil { + return nil, err + } + encryptConfig.Aws = awsConfig + } + if kesConfiguration.Keys.Gcp != nil { + gcpJSON, err := json.Marshal(kesConfiguration.Keys.Gcp) + if err != nil { + return nil, err + } + gcpConfig := &models.GcpConfiguration{} + err = json.Unmarshal(gcpJSON, gcpConfig) + if err != nil { + return nil, err + } + encryptConfig.Gcp = gcpConfig + } + if kesConfiguration.Keys.Gemalto != nil { + gemalto := kesConfiguration.Keys.Gemalto + gemaltoConfig := &models.GemaltoConfigurationResponse{ + Keysecure: &models.GemaltoConfigurationResponseKeysecure{}, + } + if gemalto.KeySecure != nil { + gemaltoConfig.Keysecure.Endpoint = &gemalto.KeySecure.Endpoint + if gemalto.KeySecure.Credentials != nil { + gemaltoConfig.Keysecure.Credentials = &models.GemaltoConfigurationResponseKeysecureCredentials{ + Domain: &gemalto.KeySecure.Credentials.Domain, + Retry: int64(gemalto.KeySecure.Credentials.Retry.Seconds()), + Token: &gemalto.KeySecure.Credentials.Token, + } + } + if gemalto.KeySecure.TLS != nil { + if tenant.KESClientCert() { + gemaltoConfig.Keysecure.TLS = &models.GemaltoConfigurationResponseKeysecureTLS{} + clientSecretName := tenant.Spec.KES.ClientCertSecret.Name + keyPair, err := clientSet.getSecret(ctx, namespace, clientSecretName, metav1.GetOptions{}) + if err != nil { + return nil, err + } + // Extract client ca certificate + if rawCert, ok := keyPair.Data["ca.crt"]; ok { + gemaltoConfig.Keysecure.TLS.Ca, err = parseCertificate(clientSecretName, rawCert) + if err != nil { + return nil, err + } + } + } + + } + } + encryptConfig.Gemalto = gemaltoConfig + } + if kesConfiguration.Keys.Azure != nil { + azureJSON, err := json.Marshal(kesConfiguration.Keys.Azure) + if err != nil { + return nil, err + } + azureConfig := &models.AzureConfiguration{} + err = json.Unmarshal(azureJSON, azureConfig) + if err != nil { + return nil, err + } + encryptConfig.Azure = azureConfig + } + } + } + return encryptConfig, nil + } + return nil, errors.New("encryption configuration not found") +} + +// getTenantEncryptionResponse is a wrapper for tenantEncryptionInfo +func getTenantEncryptionInfoResponse(session *models.Principal, params operator_api.TenantEncryptionInfoParams) (*models.EncryptionConfigurationResponse, *models.Error) { + ctx := context.Background() + // get Kubernetes Client + clientSet, err := cluster.K8sClient(session.STSSessionToken) + if err != nil { + return nil, prepareError(err, errorEncryptionConfigNotFound) + } + k8sClient := k8sClient{ + client: clientSet, + } + opClientClientSet, err := cluster.OperatorClient(session.STSSessionToken) + if err != nil { + return nil, prepareError(err, errorEncryptionConfigNotFound) + } + opClient := operatorClient{ + client: opClientClientSet, + } + configuration, err := tenantEncryptionInfo(ctx, &opClient, &k8sClient, params.Namespace, params) + if err != nil { + return nil, prepareError(err, errorEncryptionConfigNotFound) + } + return configuration, nil +} + // getKESConfiguration will generate the KES server certificate secrets, the tenant client secrets for mTLS authentication between MinIO and KES and the // kes-configuration.yaml file used by the KES service (how to connect to the external KMS, eg: Vault, AWS, Gemalto, etc) func getKESConfiguration(ctx context.Context, clientSet K8sClientI, ns string, encryptionCfg *models.EncryptionConfiguration, secretName, tenantName string) (kesConfiguration *miniov2.KESConfig, err error) { @@ -410,6 +689,10 @@ func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sCl mTLSCertificates := map[string][]byte{} // if encryption is enabled and encryption is configured to use Vault if encryptionCfg.Vault != nil { + ping := 10 // default ping + if encryptionCfg.Vault.Status != nil { + ping = int(encryptionCfg.Vault.Status.Ping) + } // Initialize Vault Config kesConfig.Keys.Vault = &kes.Vault{ Endpoint: *encryptionCfg.Vault.Endpoint, @@ -417,16 +700,17 @@ func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sCl Namespace: encryptionCfg.Vault.Namespace, Prefix: encryptionCfg.Vault.Prefix, Status: &kes.VaultStatus{ - Ping: 10 * time.Second, + Ping: time.Duration(ping) * time.Second, }, } // Vault AppRole credentials if encryptionCfg.Vault.Approle != nil { + retry := encryptionCfg.Vault.Approle.Retry 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, + Retry: time.Duration(retry) * time.Second, } } else { return nil, nil, errors.New("approle credentials missing for kes") diff --git a/pkg/kes/kes.go b/pkg/kes/kes.go index 8b6e38642..ea341d55c 100644 --- a/pkg/kes/kes.go +++ b/pkg/kes/kes.go @@ -32,87 +32,87 @@ type TLSProxyHeader struct { } type TLSProxy struct { - Identities *[]Identity `yaml:"identities,omitempty"` - Header *TLSProxyHeader `yaml:"header,omitempty"` + Identities *[]Identity `yaml:"identities,omitempty" json:"identities,omitempty"` + Header *TLSProxyHeader `yaml:"header,omitempty" json:"header,omitempty"` } type TLS struct { - KeyPath string `yaml:"key,omitempty"` - CertPath string `yaml:"cert,omitempty"` - Proxy *TLSProxy `yaml:"proxy,omitempty"` + KeyPath string `yaml:"key,omitempty" json:"key,omitempty"` + CertPath string `yaml:"cert,omitempty" json:"cert,omitempty"` + Proxy *TLSProxy `yaml:"proxy,omitempty" json:"proxy,omitempty"` } type Policy struct { - Paths []string `yaml:"paths,omitempty"` - Identities []Identity `yaml:"identities,omitempty"` + Paths []string `yaml:"paths,omitempty" json:"paths,omitempty"` + Identities []Identity `yaml:"identities,omitempty" json:"identities,omitempty"` } type Expiry struct { - Any time.Duration `yaml:"any,omitempty"` - Unused time.Duration `yaml:"unused,omitempty"` + Any time.Duration `yaml:"any,omitempty" json:"any,omitempty"` + Unused time.Duration `yaml:"unused,omitempty" json:"unused,omitempty"` } type Cache struct { - Expiry *Expiry `yaml:"expiry,omitempty"` + Expiry *Expiry `yaml:"expiry,omitempty" json:"expiry,omitempty"` } type Log struct { - Error string `yaml:"error,omitempty"` - Audit string `yaml:"audit,omitempty"` + Error string `yaml:"error,omitempty" json:"error,omitempty"` + Audit string `yaml:"audit,omitempty" json:"audit,omitempty"` } type Fs struct { - Path string `yaml:"path,omitempty"` + Path string `yaml:"path,omitempty" json:"path,omitempty"` } type AppRole struct { - EnginePath string `yaml:"engine,omitempty"` - ID string `yaml:"id,omitempty"` - Secret string `yaml:"secret,omitempty"` - Retry time.Duration `yaml:"retry,omitempty"` + EnginePath string `yaml:"engine,omitempty" json:"engine,omitempty"` + ID string `yaml:"id,omitempty" json:"id,omitempty"` + Secret string `yaml:"secret,omitempty" json:"secret,omitempty"` + Retry time.Duration `yaml:"retry,omitempty" json:"retry,omitempty"` } type VaultTLS struct { - KeyPath string `yaml:"key,omitempty"` - CertPath string `yaml:"cert,omitempty"` - CAPath string `yaml:"ca,omitempty"` + KeyPath string `yaml:"key,omitempty" json:"key,omitempty"` + CertPath string `yaml:"cert,omitempty" json:"cert,omitempty"` + CAPath string `yaml:"ca,omitempty" json:"ca,omitempty"` } type VaultStatus struct { - Ping time.Duration `yaml:"ping,omitempty"` + Ping time.Duration `yaml:"ping,omitempty" json:"ping,omitempty"` } type Vault struct { - Endpoint string `yaml:"endpoint,omitempty"` - EnginePath string `yaml:"engine,omitempty"` - Namespace string `yaml:"namespace,omitempty"` - Prefix string `yaml:"prefix,omitempty"` - AppRole *AppRole `yaml:"approle,omitempty"` - TLS *VaultTLS `yaml:"tls,omitempty"` - Status *VaultStatus `yaml:"status,omitempty"` + Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"` + EnginePath string `yaml:"engine,omitempty" json:"engine,omitempty"` + Namespace string `yaml:"namespace,omitempty" json:"namespace,omitempty"` + Prefix string `yaml:"prefix,omitempty" json:"prefix,omitempty"` + AppRole *AppRole `yaml:"approle,omitempty" json:"approle,omitempty"` + TLS *VaultTLS `yaml:"tls,omitempty" json:"tls,omitempty"` + Status *VaultStatus `yaml:"status,omitempty" json:"status,omitempty"` } type AwsSecretManagerLogin struct { - AccessKey string `yaml:"accesskey"` - SecretKey string `yaml:"secretkey"` - SessionToken string `yaml:"token"` + AccessKey string `yaml:"accesskey" json:"accesskey"` + SecretKey string `yaml:"secretkey" json:"secretkey"` + SessionToken string `yaml:"token" json:"token"` } type AwsSecretManager struct { - Endpoint string `yaml:"endpoint,omitempty"` - Region string `yaml:"region,omitempty"` - KmsKey string ` yaml:"kmskey,omitempty"` - Login *AwsSecretManagerLogin `yaml:"credentials,omitempty"` + Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"` + Region string `yaml:"region,omitempty" json:"region,omitempty"` + KmsKey string `yaml:"kmskey,omitempty" json:"kmskey,omitempty"` + Login *AwsSecretManagerLogin `yaml:"credentials,omitempty" json:"credentials,omitempty"` } type Aws struct { - SecretsManager *AwsSecretManager `yaml:"secretsmanager,omitempty"` + SecretsManager *AwsSecretManager `yaml:"secretsmanager,omitempty" json:"secretsmanager,omitempty"` } type GemaltoCredentials struct { - Token string `yaml:"token,omitempty"` - Domain string `yaml:"domain,omitempty"` - Retry time.Duration `yaml:"retry,omitempty"` + Token string `yaml:"token,omitempty" json:"token,omitempty"` + Domain string `yaml:"domain,omitempty" json:"domain,omitempty"` + Retry time.Duration `yaml:"retry,omitempty" json:"retry,omitempty"` } type GemaltoTLS struct { @@ -120,64 +120,64 @@ type GemaltoTLS struct { } type GemaltoKeySecure struct { - Endpoint string `yaml:"endpoint,omitempty"` - Credentials *GemaltoCredentials `yaml:"credentials,omitempty"` - TLS *GemaltoTLS `yaml:"tls,omitempty"` + Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"` + Credentials *GemaltoCredentials `yaml:"credentials,omitempty" json:"credentials,omitempty"` + TLS *GemaltoTLS `yaml:"tls,omitempty" json:"tls,omitempty"` } type Gemalto struct { - KeySecure *GemaltoKeySecure `yaml:"keysecure,omitempty"` + KeySecure *GemaltoKeySecure `yaml:"keysecure,omitempty" json:"keysecure,omitempty"` } type GcpCredentials struct { - ClientEmail string `yaml:"client_email"` - ClientID string `yaml:"client_id"` - PrivateKeyID string `yaml:"private_key_id"` - PrivateKey string `yaml:"private_key"` + ClientEmail string `yaml:"client_email" json:"client_email"` + ClientID string `yaml:"client_id" json:"client_id"` + PrivateKeyID string `yaml:"private_key_id" json:"private_key_id"` + PrivateKey string `yaml:"private_key" json:"private_key"` } type GcpSecretManager struct { - ProjectID string `yaml:"project_id"` - Endpoint string `yaml:"endpoint,omitempty"` - Credentials *GcpCredentials `yaml:"credentials,omitempty"` + ProjectID string `yaml:"project_id" json:"project_id"` + Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"` + Credentials *GcpCredentials `yaml:"credentials,omitempty" json:"credentials,omitempty"` } type Gcp struct { - SecretManager *GcpSecretManager `yaml:"secretmanager,omitempty"` + SecretManager *GcpSecretManager `yaml:"secretmanager,omitempty" json:"secretmanager,omitempty"` } type AzureCredentials struct { - TenantID string `yaml:"tenant_id"` - ClientID string `yaml:"client_id"` - ClientSecret string `yaml:"client_secret"` + TenantID string `yaml:"tenant_id" json:"tenant_id"` + ClientID string `yaml:"client_id" json:"client_id"` + ClientSecret string `yaml:"client_secret" json:"client_secret"` } type AzureKeyVault struct { - Endpoint string `yaml:"endpoint,omitempty"` - Credentials *AzureCredentials `yaml:"credentials,omitempty"` + Endpoint string `yaml:"endpoint,omitempty" json:"endpoint,omitempty"` + Credentials *AzureCredentials `yaml:"credentials,omitempty" json:"credentials,omitempty"` } type Azure struct { - KeyVault *AzureKeyVault `yaml:"keyvault,omitempty"` + KeyVault *AzureKeyVault `yaml:"keyvault,omitempty" json:"keyvault,omitempty"` } type Keys struct { - Fs *Fs `yaml:"fs,omitempty"` - Vault *Vault `yaml:"vault,omitempty"` - Aws *Aws `yaml:"aws,omitempty"` - Gemalto *Gemalto `yaml:"gemalto,omitempty"` - Gcp *Gcp `yaml:"gcp,omitempty"` - Azure *Azure `yaml:"azure,omitempty"` + Fs *Fs `yaml:"fs,omitempty" json:"fs,omitempty"` + Vault *Vault `yaml:"vault,omitempty" json:"vault,omitempty"` + Aws *Aws `yaml:"aws,omitempty" json:"aws,omitempty"` + Gemalto *Gemalto `yaml:"gemalto,omitempty" json:"gemalto,omitempty"` + Gcp *Gcp `yaml:"gcp,omitempty" json:"gcp,omitempty"` + Azure *Azure `yaml:"azure,omitempty" json:"azure,omitempty"` } type ServerConfig struct { - Addr string `yaml:"address,omitempty"` - Root Identity `yaml:"root,omitempty"` - TLS TLS `yaml:"tls,omitempty"` - Policies map[string]Policy `yaml:"policy,omitempty"` - Cache Cache `yaml:"cache,omitempty"` - Log Log `yaml:"log,omitempty"` - Keys Keys `yaml:"keys,omitempty"` + Addr string `yaml:"address,omitempty" json:"address,omitempty"` + Root Identity `yaml:"root,omitempty" json:"root,omitempty"` + TLS TLS `yaml:"tls,omitempty" json:"tls,omitempty"` + Policies map[string]Policy `yaml:"policy,omitempty" json:"policy,omitempty"` + Cache Cache `yaml:"cache,omitempty" json:"cache,omitempty"` + Log Log `yaml:"log,omitempty" json:"log,omitempty"` + Keys Keys `yaml:"keys,omitempty" json:"keys,omitempty"` } func ParseCertificate(cert []byte) (*x509.Certificate, error) { diff --git a/portal-ui/src/common/SecureComponent/permissions.ts b/portal-ui/src/common/SecureComponent/permissions.ts index 8c30ba7ef..e2f2e9984 100644 --- a/portal-ui/src/common/SecureComponent/permissions.ts +++ b/portal-ui/src/common/SecureComponent/permissions.ts @@ -185,6 +185,8 @@ export const IAM_PAGES = { "/namespaces/:tenantNamespace/tenants/:tenantName/license", NAMESPACE_TENANT_SECURITY: "/namespaces/:tenantNamespace/tenants/:tenantName/security", + NAMESPACE_TENANT_ENCRYPTION: + "/namespaces/:tenantNamespace/tenants/:tenantName/encryption", NAMESPACE_TENANT_MONITORING: "/namespaces/:tenantNamespace/tenants/:tenantName/monitoring", NAMESPACE_TENANT_LOGGING: diff --git a/portal-ui/src/common/types.ts b/portal-ui/src/common/types.ts index 3fa4d26bd..db1fd890a 100644 --- a/portal-ui/src/common/types.ts +++ b/portal-ui/src/common/types.ts @@ -178,6 +178,38 @@ export interface IEncryptionConfiguration { gemalto?: IGemaltoConfig; aws?: IAWSConfig; vault?: IVaultConfig; + azure?: IAzureConfig; + gcp?: IGCPConfig; +} + +export interface IGCPCredentials { + client_email: string; + client_id: string; + private_key_id: string; + private_key: string; +} + +export interface IGCPSecretManager { + project_id: string; + endpoint?: string; + credentials?: IGCPCredentials; +} +export interface IGCPConfig { + secretmanager: IGCPSecretManager; +} + +export interface IAzureCredentials { + tenant_id: string; + client_id: string; + client_secret: string; +} +export interface IAzureKeyVault { + endpoint: string; + credentials?: IAzureCredentials; +} + +export interface IAzureConfig { + keyvault: IAzureKeyVault; } export interface IVaultConfig { @@ -218,16 +250,16 @@ export interface IVaultStatusConfig { export interface IKeysecureConfig { endpoint: string; credentials: IGemaltoCredentials; - tls: IGemaltoTLS; + tls: IGemaltoTLSConfig; } export interface IGemaltoCredentials { token: string; domain: string; - retry?: number; + retry?: string; } -export interface IGemaltoTLS { +export interface IGemaltoTLSConfig { ca: string; } diff --git a/portal-ui/src/screens/Console/Console.tsx b/portal-ui/src/screens/Console/Console.tsx index 953012f5a..b569985db 100644 --- a/portal-ui/src/screens/Console/Console.tsx +++ b/portal-ui/src/screens/Console/Console.tsx @@ -446,6 +446,11 @@ const Console = ({ path: IAM_PAGES.NAMESPACE_TENANT_SECURITY, forceDisplay: true, }, + { + component: TenantDetails, + path: IAM_PAGES.NAMESPACE_TENANT_ENCRYPTION, + forceDisplay: true, + }, { component: TenantDetails, path: IAM_PAGES.NAMESPACE_TENANT_MONITORING, diff --git a/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx b/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx index e121e967c..a7a9a57d3 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx @@ -515,7 +515,7 @@ const AddTenant = ({ }; } let vaultTLS = null; - if (vaultKeyPair || vaultCA) { + if (vaultKeyPair || vaultCAInsert) { vaultTLS = { tls: { ...vaultKeyPair, 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 bb0f2c423..268b77781 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Encryption.tsx +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Encryption.tsx @@ -482,97 +482,6 @@ const Encryption = ({ {encryptionType === "vault" && ( - - { - const targetD = e.target; - const checked = targetD.checked; - - updateField("enableCustomCertsForKES", checked); - }} - label={"Custom Certificates"} - disabled={!enableAutoCert} - /> - - {(enableCustomCertsForKES || !enableAutoCert) && ( - - - -
- - Encryption Service Certificates - - { - addFileServerCert("key", fileName, encodedValue); - cleanValidation("serverKey"); - }} - accept=".key,.pem" - id="serverKey" - name="serverKey" - label="Key" - error={validationErrors["serverKey"] || ""} - value={serverCertificate.key} - required={!enableAutoCert} - /> - { - addFileServerCert("cert", fileName, encodedValue); - cleanValidation("serverCert"); - }} - accept=".cer,.crt,.cert,.pem" - id="serverCert" - name="serverCert" - label="Cert" - error={validationErrors["serverCert"] || ""} - value={serverCertificate.cert} - required={!enableAutoCert} - /> -
-
-
- - - -
- - Mutual TLS authentication - - { - addFileClientCert("key", fileName, encodedValue); - cleanValidation("clientKey"); - }} - accept=".key,.pem" - id="clientKey" - name="clientKey" - label="Key" - error={validationErrors["clientKey"] || ""} - value={clientCertificate.key} - required={!enableAutoCert} - /> - { - addFileClientCert("cert", fileName, encodedValue); - cleanValidation("clientCert"); - }} - accept=".cer,.crt,.cert,.pem" - id="clientCert" - name="clientCert" - label="Cert" - error={validationErrors["clientCert"] || ""} - value={clientCertificate.cert} - required={!enableAutoCert} - /> -
-
-
-
- )}

Additional Configurations

+ + { + const targetD = e.target; + const checked = targetD.checked; + + updateField("enableCustomCertsForKES", checked); + }} + label={"Custom Certificates"} + disabled={!enableAutoCert} + /> + + {(enableCustomCertsForKES || !enableAutoCert) && ( + + + +
+ + Encryption Service Certificates + + { + addFileServerCert("key", fileName, encodedValue); + cleanValidation("serverKey"); + }} + accept=".key,.pem" + id="serverKey" + name="serverKey" + label="Key" + error={validationErrors["serverKey"] || ""} + value={serverCertificate.key} + required={!enableAutoCert} + /> + { + addFileServerCert("cert", fileName, encodedValue); + cleanValidation("serverCert"); + }} + accept=".cer,.crt,.cert,.pem" + id="serverCert" + name="serverCert" + label="Cert" + error={validationErrors["serverCert"] || ""} + value={serverCertificate.cert} + required={!enableAutoCert} + /> +
+
+
+ + +
+ + Mutual TLS authentication with MinIO + + { + addFileClientCert("key", fileName, encodedValue); + cleanValidation("clientKey"); + }} + accept=".key,.pem" + id="clientKey" + name="clientKey" + label="Key" + error={validationErrors["clientKey"] || ""} + value={clientCertificate.key} + required={!enableAutoCert} + /> + { + addFileClientCert("cert", fileName, encodedValue); + cleanValidation("clientCert"); + }} + accept=".cer,.crt,.cert,.pem" + id="clientCert" + name="clientCert" + label="Cert" + error={validationErrors["clientCert"] || ""} + value={clientCertificate.cert} + required={!enableAutoCert} + /> +
+
+
+
+ )} import("./TenantYAML"))); const TenantSummary = withSuspense(React.lazy(() => import("./TenantSummary"))); @@ -69,6 +70,9 @@ const TenantVolumes = withSuspense( const TenantSecurity = withSuspense( React.lazy(() => import("./TenantSecurity")) ); +const TenantEncryption = withSuspense( + React.lazy(() => import("./TenantEncryption")) +); const DeleteTenant = withSuspense( React.lazy(() => import("../ListTenants/DeleteTenant")) ); @@ -301,10 +305,10 @@ const TenantDetails = ({ return health_status === "red" ? classes.redState : health_status === "yellow" - ? classes.yellowState - : health_status === "green" - ? classes.greenState - : classes.greyState; + ? classes.yellowState + : health_status === "green" + ? classes.greenState + : classes.greyState; }; return ( @@ -420,59 +424,63 @@ const TenantDetails = ({ + ( . + +import { ITenant } from "../ListTenants/types"; +import { + ICertificateInfo, + ITenantEncryptionResponse, + ISecurityContext, +} from "../types"; +import { Theme } from "@mui/material/styles"; +import createStyles from "@mui/styles/createStyles"; +import withStyles from "@mui/styles/withStyles"; +import { + containerForHeader, + createTenantCommon, + formFieldStyles, + modalBasic, + spacingUtils, + tenantDetailsStyles, + wizardCommon, +} from "../../Common/FormComponents/common/styleLibrary"; +import Paper from "@mui/material/Paper"; +import React, { Fragment, useEffect, useState } from "react"; +import { setErrorSnackMessage } from "../../../../actions"; +import { connect } from "react-redux"; +import { AppState } from "../../../../store"; +import { setTenantDetailsLoad } from "../actions"; +import api from "../../../../common/api"; +import { ErrorResponseHandler } from "../../../../common/types"; + +import FormSwitchWrapper from "../../Common/FormComponents/FormSwitchWrapper/FormSwitchWrapper"; +import Grid from "@mui/material/Grid"; +import FileSelector from "../../Common/FormComponents/FileSelector/FileSelector"; +import InputBoxWrapper from "../../Common/FormComponents/InputBoxWrapper/InputBoxWrapper"; +import RadioGroupSelector from "../../Common/FormComponents/RadioGroupSelector/RadioGroupSelector"; +import { Button, DialogContentText, Typography } from "@mui/material"; +import Chip from "@mui/material/Chip"; +import Moment from "react-moment"; +import VisibilityOffIcon from "@mui/icons-material/VisibilityOff"; +import RemoveRedEyeIcon from "@mui/icons-material/RemoveRedEye"; +import { KeyPair } from "../ListTenants/utils"; +import { clearValidationError } from "../utils"; +import { + commonFormValidation, + IValidation, +} from "../../../../utils/validationFunctions"; +import ConfirmDialog from "../../Common/ModalWrapper/ConfirmDialog"; + +interface ITenantEncryption { + classes: any; + loadingTenant: boolean; + tenant: ITenant | null; + setErrorSnackMessage: typeof setErrorSnackMessage; + setTenantDetailsLoad: typeof setTenantDetailsLoad; +} + +const styles = (theme: Theme) => + createStyles({ + ...tenantDetailsStyles, + ...spacingUtils, + loaderAlign: { + textAlign: "center", + }, + title: { + marginTop: 35, + }, + bold: { fontWeight: "bold" }, + italic: { fontStyle: "italic" }, + paperContainer: { + padding: "15px 15px 15px 50px", + }, + certificateInfo: { + height: "auto", + margin: 5, + }, + fileItem: { + marginRight: 10, + display: "flex", + "& div label": { + minWidth: 50, + }, + + "@media (max-width: 900px)": { + flexFlow: "column", + }, + }, + certInputRow: { + display: "flex", + alignItems: "center", + borderBottom: "1px solid #eaeaea", + marginBottom: 10, + }, + caCertsRow: { + borderBottom: "1px solid #eaeaea", + display: "flex", + alignItems: "center", + marginBottom: 10, + }, + ...containerForHeader(theme.spacing(4)), + ...createTenantCommon, + ...formFieldStyles, + ...modalBasic, + ...wizardCommon, + }); + +const TenantEncryption = ({ + classes, + tenant, + setErrorSnackMessage, +}: ITenantEncryption) => { + const [encryptionEnabled, setEncryptionEnabled] = useState(false); + const [encryptionType, setEncryptionType] = useState("vault"); + const [replicas, setReplicas] = useState("2"); + const [image, setImage] = useState(""); + const [refreshEncryptionInfo, setRefreshEncryptionInfo] = + useState(false); + const [securityContext, setSecurityContext] = useState({ + fsGroup: "1000", + runAsGroup: "1000", + runAsNonRoot: true, + runAsUser: "1000", + }); + const [vaultConfiguration, setVaultConfiguration] = useState(null); + const [awsConfiguration, setAWSConfiguration] = useState(null); + const [gemaltoConfiguration, setGemaltoConfiguration] = useState(null); + const [azureConfiguration, setAzureConfiguration] = useState(null); + const [gcpConfiguration, setGCPConfiguration] = useState(null); + const [enabledCustomCertificates, setEnabledCustomCertificates] = + useState(false); + const [updatingEncryption, setUpdatingEncryption] = useState(false); + const [serverTLSCertificateSecret, setServerTLSCertificateSecret] = + useState(null); + const [mTLSCertificateSecret, setMTLSCertificateSecret] = + useState(null); + const [mTLSCertificate, setMTLSCertificate] = useState(null); + const [certificatesToBeRemoved, setCertificatesToBeRemoved] = useState< + string[] + >([]); + const [showVaultAppRoleID, setShowVaultAppRoleID] = useState(false); + const [isFormValid, setIsFormValid] = useState(false); + const [showVaultAppRoleSecret, setShowVaultAppRoleSecret] = + useState(false); + const [vaultClientCertificateSecret, setVaultClientCertificateSecret] = + useState(null); + const [vaultCACertificateSecret, setVaultCACertificateSecret] = + useState(null); + const [vaultClientCertificate, setVaultClientCertificate] = + useState(null); + const [serverCertificate, setServerCertificate] = useState( + null + ); + const [vaultCACertificate, setVaultCACertificate] = useState( + null + ); + const [gemaltoCACertificateSecret, setGemaltoCACertificateSecret] = + useState(null); + const [gemaltoCACertificate, setGemaltotCACertificate] = + useState(null); + const [validationErrors, setValidationErrors] = useState({}); + const cleanValidation = (fieldName: string) => { + setValidationErrors(clearValidationError(validationErrors, fieldName)); + }; + const [confirmOpen, setConfirmOpen] = useState(false); + + // Validation + useEffect(() => { + let encryptionValidation: IValidation[] = []; + + if (encryptionEnabled) { + encryptionValidation = [ + ...encryptionValidation, + { + fieldKey: "replicas", + required: true, + value: replicas, + customValidation: parseInt(replicas) < 1, + customValidationMessage: "Replicas needs to be 1 or greater", + }, + { + fieldKey: "kes_securityContext_runAsUser", + required: true, + value: securityContext.runAsUser, + customValidation: + securityContext.runAsUser === "" || + parseInt(securityContext.runAsUser) < 0, + customValidationMessage: `runAsUser must be present and be 0 or more`, + }, + { + fieldKey: "kes_securityContext_runAsGroup", + required: true, + value: securityContext.runAsGroup, + customValidation: + securityContext.runAsGroup === "" || + parseInt(securityContext.runAsGroup) < 0, + customValidationMessage: `runAsGroup must be present and be 0 or more`, + }, + { + fieldKey: "kes_securityContext_fsGroup", + required: true, + value: securityContext.fsGroup, + customValidation: + securityContext.fsGroup === "" || + parseInt(securityContext.fsGroup) < 0, + customValidationMessage: `fsGroup must be present and be 0 or more`, + }, + ]; + + if (enabledCustomCertificates) { + encryptionValidation = [ + ...encryptionValidation, + { + fieldKey: "serverKey", + required: false, + value: serverCertificate?.encoded_key || "", + }, + { + fieldKey: "serverCert", + required: false, + value: serverCertificate?.encoded_cert || "", + }, + { + fieldKey: "clientKey", + required: false, + value: mTLSCertificate?.encoded_key || "", + }, + { + fieldKey: "clientCert", + required: false, + value: mTLSCertificate?.encoded_cert || "", + }, + ]; + } + + if (encryptionType === "vault") { + encryptionValidation = [ + ...encryptionValidation, + { + fieldKey: "vault_endpoint", + required: true, + value: vaultConfiguration?.endpoint, + }, + { + fieldKey: "vault_id", + required: true, + value: vaultConfiguration?.approle?.id, + }, + { + fieldKey: "vault_secret", + required: true, + value: vaultConfiguration?.approle?.secret, + }, + { + fieldKey: "vault_ping", + required: false, + value: vaultConfiguration?.status?.ping, + customValidation: parseInt(vaultConfiguration?.status?.ping) < 0, + customValidationMessage: "Value needs to be 0 or greater", + }, + { + fieldKey: "vault_retry", + required: false, + value: vaultConfiguration?.approle?.retry, + customValidation: parseInt(vaultConfiguration?.approle?.retry) < 0, + customValidationMessage: "Value needs to be 0 or greater", + }, + ]; + } + + if (encryptionType === "aws") { + encryptionValidation = [ + ...encryptionValidation, + { + fieldKey: "aws_endpoint", + required: true, + value: awsConfiguration?.secretsmanager?.endpoint, + }, + { + fieldKey: "aws_region", + required: true, + value: awsConfiguration?.secretsmanager?.region, + }, + { + fieldKey: "aws_accessKey", + required: true, + value: awsConfiguration?.secretsmanager?.credentials?.accesskey, + }, + { + fieldKey: "aws_secretKey", + required: true, + value: awsConfiguration?.secretsmanager?.credentials?.secretkey, + }, + ]; + } + + if (encryptionType === "gemalto") { + encryptionValidation = [ + ...encryptionValidation, + { + fieldKey: "gemalto_endpoint", + required: true, + value: gemaltoConfiguration?.keysecure?.endpoint, + }, + { + fieldKey: "gemalto_token", + required: true, + value: gemaltoConfiguration?.keysecure?.credentials?.token, + }, + { + fieldKey: "gemalto_domain", + required: true, + value: gemaltoConfiguration?.keysecure?.credentials?.domain, + }, + { + fieldKey: "gemalto_retry", + required: false, + value: gemaltoConfiguration?.keysecure?.credentials?.retry, + customValidation: + parseInt(gemaltoConfiguration?.keysecure?.credentials?.retry) < 0, + customValidationMessage: "Value needs to be 0 or greater", + }, + ]; + } + + if (encryptionType === "azure") { + encryptionValidation = [ + ...encryptionValidation, + { + fieldKey: "azure_endpoint", + required: true, + value: azureConfiguration?.keyvault?.endpoint, + }, + { + fieldKey: "azure_tenant_id", + required: true, + value: azureConfiguration?.keyvault?.credentials?.tenant_id, + }, + { + fieldKey: "azure_client_id", + required: true, + value: azureConfiguration?.keyvault?.credentials?.client_id, + }, + { + fieldKey: "azure_client_secret", + required: true, + value: azureConfiguration?.keyvault?.credentials?.client_secret, + }, + ]; + } + } + + const commonVal = commonFormValidation(encryptionValidation); + + setIsFormValid(Object.keys(commonVal).length === 0); + + setValidationErrors(commonVal); + }, [ + enabledCustomCertificates, + encryptionEnabled, + encryptionType, + serverCertificate?.encoded_key, + serverCertificate?.encoded_cert, + mTLSCertificate?.encoded_key, + mTLSCertificate?.encoded_cert, + vaultClientCertificate?.encoded_key, + vaultClientCertificate?.encoded_cert, + vaultCACertificate?.encoded_key, + vaultCACertificate?.encoded_cert, + securityContext, + vaultConfiguration, + awsConfiguration, + gemaltoConfiguration, + azureConfiguration, + gcpConfiguration, + replicas, + ]); + + const fetchEncryptionInfo = () => { + if (!refreshEncryptionInfo) { + setRefreshEncryptionInfo(true); + api + .invoke( + "GET", + `/api/v1/namespaces/${tenant?.namespace}/tenants/${tenant?.name}/encryption` + ) + .then((resp: ITenantEncryptionResponse) => { + if (resp.vault) { + setEncryptionType("vault"); + setVaultConfiguration(resp.vault); + if (resp.vault.tls) { + setVaultClientCertificateSecret(resp.vault.tls.crt); + setVaultCACertificateSecret(resp.vault.tls.ca); + } + } else if (resp.aws) { + setEncryptionType("aws"); + setAWSConfiguration(resp.aws); + } else if (resp.gemalto) { + setEncryptionType("gemalto"); + setGemaltoConfiguration(resp.gemalto); + if (resp.gemalto.keysecure.tls) { + setGemaltoCACertificateSecret(resp.gemalto.keysecure.tls.ca); + } + } else if (resp.gcp) { + setEncryptionType("gcp"); + setGCPConfiguration(resp.gcp); + } else if (resp.azure) { + setEncryptionType("azure"); + setAzureConfiguration(resp.azure); + } + + setEncryptionEnabled(true); + setImage(resp.image); + setReplicas(resp.replicas); + if (resp.securityContext) { + setSecurityContext(resp.securityContext); + } + if (resp.server || resp.mtls_client) { + setEnabledCustomCertificates(true); + } + if (resp.server) { + setServerTLSCertificateSecret(resp.server); + } + if (resp.mtls_client) { + setMTLSCertificateSecret(resp.mtls_client); + } + setRefreshEncryptionInfo(false); + }) + .catch((err: ErrorResponseHandler) => { + console.log(err); + setRefreshEncryptionInfo(false); + }); + } + }; + + useEffect(() => { + fetchEncryptionInfo(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const removeCertificate = (certificateInfo: ICertificateInfo) => { + setCertificatesToBeRemoved([ + ...certificatesToBeRemoved, + certificateInfo.name, + ]); + if (certificateInfo.name === serverTLSCertificateSecret?.name) { + setServerTLSCertificateSecret(null); + } + if (certificateInfo.name === mTLSCertificateSecret?.name) { + setMTLSCertificateSecret(null); + } + if (certificateInfo.name === vaultClientCertificateSecret?.name) { + setVaultClientCertificateSecret(null); + } + if (certificateInfo.name === vaultCACertificateSecret?.name) { + setVaultCACertificateSecret(null); + } + if (certificateInfo.name === gemaltoCACertificateSecret?.name) { + setGemaltoCACertificateSecret(null); + } + }; + + const updateEncryptionConfiguration = () => { + if (encryptionEnabled) { + let insertEncrypt = {}; + switch (encryptionType) { + case "gemalto": + let gemaltoCAIntroduce = {}; + + if (gemaltoCACertificate?.encoded_cert) { + gemaltoCAIntroduce = { + tls: { + ca: gemaltoCACertificate?.encoded_cert, + }, + }; + } + insertEncrypt = { + gemalto: { + keysecure: { + endpoint: gemaltoConfiguration?.keysecure?.endpoint || "", + credentials: { + token: + gemaltoConfiguration?.keysecure?.credentials?.token || "", + domain: + gemaltoConfiguration?.keysecure?.credentials?.domain || "", + retry: parseInt( + gemaltoConfiguration?.keysecure?.credentials?.retry + ), + }, + ...gemaltoCAIntroduce, + }, + }, + }; + break; + case "aws": + insertEncrypt = { + aws: { + secretsmanager: { + endpoint: awsConfiguration?.secretsmanager?.endpoint || "", + region: awsConfiguration?.secretsmanager?.region || "", + kmskey: awsConfiguration?.secretsmanager?.kmskey || "", + credentials: { + accesskey: + awsConfiguration?.secretsmanager?.credentials?.accesskey || + "", + secretkey: + awsConfiguration?.secretsmanager?.credentials?.secretkey || + "", + token: + awsConfiguration?.secretsmanager?.credentials?.token || "", + }, + }, + }, + }; + break; + case "azure": + insertEncrypt = { + azure: { + keyvault: { + endpoint: azureConfiguration?.keyvault?.endpoint || "", + credentials: { + tenant_id: + azureConfiguration?.keyvault?.credentials?.tenant_id || "", + client_id: + azureConfiguration?.keyvault?.credentials?.client_id || "", + client_secret: + azureConfiguration?.keyvault?.credentials?.client_secret || + "", + }, + }, + }, + }; + break; + case "gcp": + insertEncrypt = { + gcp: { + secretmanager: { + project_id: gcpConfiguration?.secretmanager?.project_id || "", + endpoint: gcpConfiguration?.secretmanager?.endpoint || "", + credentials: { + client_email: + gcpConfiguration?.secretmanager?.credentials + ?.client_email || "", + client_id: + gcpConfiguration?.secretmanager?.credentials?.client_id || + "", + private_key_id: + gcpConfiguration?.secretmanager?.credentials + ?.private_key_id || "", + private_key: + gcpConfiguration?.secretmanager?.credentials?.private_key || + "", + }, + }, + }, + }; + break; + case "vault": + let vaultKeyPair = null; + let vaultCAInsert = null; + if ( + vaultClientCertificate?.encoded_key && + vaultClientCertificate?.encoded_cert + ) { + vaultKeyPair = { + key: vaultClientCertificate?.encoded_key, + crt: vaultClientCertificate?.encoded_cert, + }; + } + if (vaultCACertificate?.encoded_cert) { + vaultCAInsert = { + ca: vaultCACertificate?.encoded_cert, + }; + } + let vaultTLS = null; + if (vaultKeyPair || vaultCAInsert) { + vaultTLS = { + tls: { + ...vaultKeyPair, + ...vaultCAInsert, + }, + }; + } + insertEncrypt = { + vault: { + endpoint: vaultConfiguration?.endpoint || "", + engine: vaultConfiguration?.engine || "", + namespace: vaultConfiguration?.namespace || "", + prefix: vaultConfiguration?.prefix || "", + approle: { + engine: vaultConfiguration?.approle?.engine || "", + id: vaultConfiguration?.approle?.id || "", + secret: vaultConfiguration?.approle?.secret || "", + retry: parseInt(vaultConfiguration?.approle?.retry), + }, + ...vaultTLS, + status: { + ping: parseInt(vaultConfiguration?.status?.ping), + }, + }, + }; + break; + } + + let encryptionServerKeyPair: any = {}; + let encryptionClientKeyPair: any = {}; + + if (mTLSCertificate?.encoded_key && mTLSCertificate?.encoded_cert) { + encryptionClientKeyPair = { + client: { + key: mTLSCertificate?.encoded_key, + crt: mTLSCertificate?.encoded_cert, + }, + }; + } + + if (serverCertificate?.encoded_key && serverCertificate?.encoded_cert) { + encryptionServerKeyPair = { + server: { + key: serverCertificate?.encoded_key, + crt: serverCertificate?.encoded_cert, + }, + }; + } + const dataSend = { + secretsToBeDeleted: certificatesToBeRemoved || [], + replicas: replicas, + securityContext: securityContext, + image: image, + ...encryptionClientKeyPair, + ...encryptionServerKeyPair, + ...insertEncrypt, + }; + if (!updatingEncryption) { + setUpdatingEncryption(true); + api + .invoke( + "PUT", + `/api/v1/namespaces/${tenant?.namespace}/tenants/${tenant?.name}/encryption`, + dataSend + ) + .then(() => { + setConfirmOpen(false); + setUpdatingEncryption(false); + fetchEncryptionInfo(); + }) + .catch((err: ErrorResponseHandler) => { + setUpdatingEncryption(false); + setConfirmOpen(false); + setErrorSnackMessage(err); + }); + } + } else { + if (!updatingEncryption) { + setUpdatingEncryption(true); + api + .invoke( + "DELETE", + `/api/v1/namespaces/${tenant?.namespace}/tenants/${tenant?.name}/encryption`, + {} + ) + .then(() => { + fetchEncryptionInfo(); + setUpdatingEncryption(false); + }) + .catch((err: ErrorResponseHandler) => { + setUpdatingEncryption(false); + setErrorSnackMessage(err); + }); + } + } + }; + + return ( + + + {confirmOpen && ( + setConfirmOpen(false)} + onConfirm={updateEncryptionConfiguration} + confirmationContent={ + + {encryptionEnabled + ? "Data will be encrypted using and external KMS" + : "Current encrypted information will not be accessible"} + + } + /> + )} +

Encryption

+
+ { + setEncryptionEnabled(!encryptionEnabled); + }} + description="" + /> +
+ {encryptionEnabled && ( + + + + { + setEncryptionType(e.target.value); + }} + selectorOptions={[ + { label: "Vault", value: "vault" }, + { label: "AWS", value: "aws" }, + { label: "Gemalto", value: "gemalto" }, + { label: "GCP", value: "gcp" }, + { label: "Azure", value: "azure" }, + ]} + /> + + {encryptionType === "vault" && ( + + + ) => + setVaultConfiguration({ + ...vaultConfiguration, + endpoint: e.target.value, + }) + } + label="Endpoint" + value={vaultConfiguration?.endpoint || ""} + error={validationErrors["vault_ping"] || ""} + required + /> + + + ) => + setVaultConfiguration({ + ...vaultConfiguration, + engine: e.target.value, + }) + } + label="Engine" + value={vaultConfiguration?.engine || ""} + /> + + + ) => + setVaultConfiguration({ + ...vaultConfiguration, + namespace: e.target.value, + }) + } + label="Namespace" + value={vaultConfiguration?.namespace || ""} + /> + + + ) => + setVaultConfiguration({ + ...vaultConfiguration, + prefix: e.target.value, + }) + } + label="Prefix" + value={vaultConfiguration?.prefix || ""} + /> + + + +
+ + App Role + + + ) => + setVaultConfiguration({ + ...vaultConfiguration, + approle: { + ...vaultConfiguration?.approle, + engine: e.target.value, + }, + }) + } + label="Engine" + value={vaultConfiguration?.approle?.engine || ""} + /> + + + ) => + setVaultConfiguration({ + ...vaultConfiguration, + approle: { + ...vaultConfiguration?.approle, + id: e.target.value, + }, + }) + } + label="AppRole ID" + value={vaultConfiguration?.approle?.id || ""} + required + error={validationErrors["vault_id"] || ""} + overlayIcon={ + showVaultAppRoleID ? ( + + ) : ( + + ) + } + overlayAction={() => + setShowVaultAppRoleID(!showVaultAppRoleID) + } + /> + + + ) => + setVaultConfiguration({ + ...vaultConfiguration, + approle: { + ...vaultConfiguration?.approle, + secret: e.target.value, + }, + }) + } + label="AppRole Secret" + value={vaultConfiguration?.approle?.secret || ""} + required + error={validationErrors["vault_secret"] || ""} + overlayIcon={ + showVaultAppRoleSecret ? ( + + ) : ( + + ) + } + overlayAction={() => + setShowVaultAppRoleSecret(!showVaultAppRoleSecret) + } + /> + + + ) => + setVaultConfiguration({ + ...vaultConfiguration, + approle: { + ...vaultConfiguration?.approle, + retry: e.target.value, + }, + }) + } + label="Retry (Seconds)" + error={validationErrors["vault_retry"] || ""} + value={vaultConfiguration?.approle?.retry || ""} + /> + +
+
+ +
+ + Mutual TLS authentication with KMS (optional) + + {vaultClientCertificateSecret ? ( + + + {vaultClientCertificateSecret.name} + + + {vaultClientCertificateSecret.domains && + vaultClientCertificateSecret.domains.map( + (dom) => { + return
{dom}
; + } + )} +
+ + Expiry:  + + + + {vaultClientCertificateSecret.expiry} + + + + } + onDelete={() => + removeCertificate(vaultClientCertificateSecret) + } + /> + ) : ( + + + setVaultClientCertificate({ + encoded_key: encodedValue || "", + id: vaultClientCertificate?.id || "", + key: fileName || "", + cert: vaultClientCertificate?.cert || "", + encoded_cert: + vaultClientCertificate?.encoded_cert || "", + }) + } + accept=".key,.pem" + id="vault_key" + name="vault_key" + label="Key" + value={vaultClientCertificate?.key || ""} + /> + + setVaultClientCertificate({ + encoded_key: + vaultClientCertificate?.encoded_key || "", + id: vaultClientCertificate?.id || "", + key: vaultClientCertificate?.key || "", + cert: fileName || "", + encoded_cert: encodedValue || "", + }) + } + accept=".cer,.crt,.cert,.pem" + id="vault_cert" + name="vault_cert" + label="Cert" + value={vaultClientCertificate?.cert || ""} + /> + + )} +
+
+ + KMS CA certificate (optional) + + {vaultCACertificateSecret ? ( + + + {vaultCACertificateSecret.name} + + + {vaultCACertificateSecret.domains && + vaultCACertificateSecret.domains.map( + (dom) => { + return
{dom}
; + } + )} +
+ + Expiry:  + + + + {vaultCACertificateSecret.expiry} + + + + } + onDelete={() => + removeCertificate(vaultCACertificateSecret) + } + /> + ) : ( + + setVaultCACertificate({ + encoded_key: + vaultCACertificate?.encoded_key || "", + id: vaultCACertificate?.id || "", + key: vaultCACertificate?.key || "", + cert: fileName || "", + encoded_cert: encodedValue || "", + }) + } + accept=".cer,.crt,.cert,.pem" + id="vault_ca" + name="vault_ca" + label="CA" + value={vaultCACertificate?.cert || ""} + /> + )} +
+
+ +
+ + Status + + ) => + setVaultConfiguration({ + ...vaultConfiguration, + status: { + ...vaultConfiguration?.status, + ping: e.target.value, + }, + }) + } + label="Ping (Seconds)" + error={validationErrors["vault_ping"] || ""} + value={vaultConfiguration?.status?.ping || ""} + /> +
+
+
+ )} + {encryptionType === "azure" && ( + + + ) => + setAzureConfiguration({ + ...azureConfiguration, + keyvault: { + ...azureConfiguration?.keyvault, + endpoint: e.target.value, + }, + }) + } + label="Endpoint" + error={validationErrors["azure_endpoint"] || ""} + value={azureConfiguration?.keyvault?.endpoint || ""} + /> + + +
+ + Credentials + + + ) => + setAzureConfiguration({ + ...azureConfiguration, + keyvault: { + ...azureConfiguration?.keyvault, + credentials: { + ...azureConfiguration?.keyvault?.credentials, + tenant_id: e.target.value, + }, + }, + }) + } + label="Tenant ID" + value={ + azureConfiguration?.keyvault?.credentials + ?.tenant_id || "" + } + error={validationErrors["azure_tenant_id"] || ""} + /> + + + ) => + setAzureConfiguration({ + ...azureConfiguration, + keyvault: { + ...azureConfiguration?.keyvault, + credentials: { + ...azureConfiguration?.keyvault?.credentials, + client_id: e.target.value, + }, + }, + }) + } + label="Client ID" + value={ + azureConfiguration?.keyvault?.credentials + ?.client_id || "" + } + error={validationErrors["azure_client_id"] || ""} + /> + + + ) => + setAzureConfiguration({ + ...azureConfiguration, + keyvault: { + ...azureConfiguration?.keyvault, + credentials: { + ...azureConfiguration?.keyvault?.credentials, + client_secret: e.target.value, + }, + }, + }) + } + label="Client Secret" + value={ + azureConfiguration?.keyvault?.credentials + ?.client_secret || "" + } + error={validationErrors["azure_client_secret"] || ""} + /> + +
+
+
+ )} + {encryptionType === "gcp" && ( + + + ) => + setGCPConfiguration({ + ...gcpConfiguration, + secretmanager: { + ...gcpConfiguration?.secretmanager, + project_id: e.target.value, + }, + }) + } + label="Project ID" + value={gcpConfiguration?.secretmanager.project_id || ""} + /> + + + ) => + setGCPConfiguration({ + ...gcpConfiguration, + secretmanager: { + ...gcpConfiguration?.secretmanager, + endpoint: e.target.value, + }, + }) + } + label="Endpoint" + value={gcpConfiguration?.secretmanager.endpoint || ""} + /> + + +
+ + Credentials + + + ) => + setGCPConfiguration({ + ...gcpConfiguration, + secretmanager: { + ...gcpConfiguration?.secretmanager, + credentials: { + ...gcpConfiguration?.secretmanager + .credentials, + client_email: e.target.value, + }, + }, + }) + } + label="Client Email" + value={ + gcpConfiguration?.secretmanager.credentials + ?.client_email || "" + } + /> + + + ) => + setGCPConfiguration({ + ...gcpConfiguration, + secretmanager: { + ...gcpConfiguration?.secretmanager, + credentials: { + ...gcpConfiguration?.secretmanager + .credentials, + client_id: e.target.value, + }, + }, + }) + } + label="Client ID" + value={ + gcpConfiguration?.secretmanager.credentials + ?.client_id || "" + } + /> + + + ) => + setGCPConfiguration({ + ...gcpConfiguration, + secretmanager: { + ...gcpConfiguration?.secretmanager, + credentials: { + ...gcpConfiguration?.secretmanager + .credentials, + private_key_id: e.target.value, + }, + }, + }) + } + label="Private Key ID" + value={ + gcpConfiguration?.secretmanager.credentials + ?.private_key_id || "" + } + /> + + + ) => + setGCPConfiguration({ + ...gcpConfiguration, + secretmanager: { + ...gcpConfiguration?.secretmanager, + credentials: { + ...gcpConfiguration?.secretmanager + .credentials, + private_key: e.target.value, + }, + }, + }) + } + label="Private Key" + value={ + gcpConfiguration?.secretmanager.credentials + ?.private_key || "" + } + /> + +
+
+
+ )} + {encryptionType === "aws" && ( + + + ) => + setAWSConfiguration({ + ...awsConfiguration, + secretsmanager: { + ...awsConfiguration?.secretsmanager, + endpoint: e.target.value, + }, + }) + } + label="Endpoint" + value={awsConfiguration?.secretsmanager?.endpoint || ""} + required + error={validationErrors["aws_endpoint"] || ""} + /> + + + ) => + setAWSConfiguration({ + ...awsConfiguration, + secretsmanager: { + ...awsConfiguration?.secretsmanager, + region: e.target.value, + }, + }) + } + label="Region" + value={awsConfiguration?.secretsmanager?.region || ""} + error={validationErrors["aws_region"] || ""} + required + /> + + + ) => + setAWSConfiguration({ + ...awsConfiguration, + secretsmanager: { + ...awsConfiguration?.secretsmanager, + kmskey: e.target.value, + }, + }) + } + label="KMS Key" + value={awsConfiguration?.secretsmanager?.kmskey || ""} + /> + + +
+ + Credentials + + + ) => + setAWSConfiguration({ + ...awsConfiguration, + secretsmanager: { + ...awsConfiguration?.secretsmanager, + credentials: { + ...awsConfiguration?.secretsmanager + ?.credentials, + accesskey: e.target.value, + }, + }, + }) + } + label="Access Key" + value={ + awsConfiguration?.secretsmanager?.credentials + ?.accesskey || "" + } + error={validationErrors["aws_accessKey"] || ""} + required + /> + + + ) => + setAWSConfiguration({ + ...awsConfiguration, + secretsmanager: { + ...awsConfiguration?.secretsmanager, + credentials: { + ...awsConfiguration?.secretsmanager + ?.credentials, + secretkey: e.target.value, + }, + }, + }) + } + label="Secret Key" + value={ + awsConfiguration?.secretsmanager?.credentials + ?.secretkey || "" + } + error={validationErrors["aws_secretKey"] || ""} + required + /> + + + ) => + setAWSConfiguration({ + ...awsConfiguration, + secretsmanager: { + ...awsConfiguration?.secretsmanager, + credentials: { + ...awsConfiguration?.secretsmanager + ?.credentials, + token: e.target.value, + }, + }, + }) + } + label="Token" + value={ + awsConfiguration?.secretsmanager?.credentials + ?.token || "" + } + /> + +
+
+
+ )} + {encryptionType === "gemalto" && ( + + + ) => + setGemaltoConfiguration({ + ...gemaltoConfiguration, + keysecure: { + ...gemaltoConfiguration?.keysecure, + endpoint: e.target.value, + }, + }) + } + label="Endpoint" + value={gemaltoConfiguration?.keysecure?.endpoint || ""} + error={validationErrors["gemalto_endpoint"] || ""} + required + /> + + +
+ + Credentials + + + ) => + setGemaltoConfiguration({ + ...gemaltoConfiguration, + keysecure: { + ...gemaltoConfiguration?.keysecure, + credentials: { + ...gemaltoConfiguration?.keysecure + ?.credentials, + token: e.target.value, + }, + }, + }) + } + label="Token" + value={ + gemaltoConfiguration?.keysecure?.credentials + ?.token || "" + } + error={validationErrors["gemalto_token"] || ""} + required + /> + + + ) => + setGemaltoConfiguration({ + ...gemaltoConfiguration, + keysecure: { + ...gemaltoConfiguration?.keysecure, + credentials: { + ...gemaltoConfiguration?.keysecure + ?.credentials, + domain: e.target.value, + }, + }, + }) + } + label="Domain" + value={ + gemaltoConfiguration?.keysecure?.credentials + ?.domain || "" + } + error={validationErrors["gemalto_domain"] || ""} + required + /> + + + ) => + setGemaltoConfiguration({ + ...gemaltoConfiguration, + keysecure: { + ...gemaltoConfiguration?.keysecure, + credentials: { + ...gemaltoConfiguration?.keysecure + ?.credentials, + retry: e.target.value, + }, + }, + }) + } + label="Retry (seconds)" + value={ + gemaltoConfiguration?.keysecure?.credentials + ?.retry || "" + } + error={validationErrors["gemalto_retry"] || ""} + /> + +
+
+ +
+ + Custom CA Root certificate verification + + {}} + accept=".cer,.crt,.cert,.pem" + id="gemalto_ca" + name="gemalto_ca" + label="CA" + value={""} + /> + {gemaltoCACertificateSecret ? ( + + + {gemaltoCACertificateSecret.name} + + + {gemaltoCACertificateSecret.domains && + gemaltoCACertificateSecret.domains.map( + (dom) => { + return
{dom}
; + } + )} +
+ + Expiry:  + + + + {gemaltoCACertificateSecret.expiry} + + + + } + onDelete={() => + removeCertificate(gemaltoCACertificateSecret) + } + /> + ) : ( + + setGemaltotCACertificate({ + encoded_key: + gemaltoCACertificate?.encoded_key || "", + id: gemaltoCACertificate?.id || "", + key: gemaltoCACertificate?.key || "", + cert: fileName || "", + encoded_cert: encodedValue || "", + }) + } + accept=".cer,.crt,.cert,.pem" + id="gemalto_ca" + name="gemalto_ca" + label="CA" + value={gemaltoCACertificate?.cert || ""} + /> + )} +
+
+
+ )} +
+

Additional Configurations

+
+ + + setEnabledCustomCertificates(!enabledCustomCertificates) + } + label={"Custom Certificates"} + /> + + {enabledCustomCertificates && ( + + + +
+ + Encryption Service Certificates + + {serverTLSCertificateSecret ? ( + + + {serverTLSCertificateSecret.name} + + + {serverTLSCertificateSecret.domains && + serverTLSCertificateSecret.domains.map( + (dom) => { + return
{dom}
; + } + )} +
+ + Expiry:  + + + + {serverTLSCertificateSecret.expiry} + + + + } + onDelete={() => + removeCertificate(serverTLSCertificateSecret) + } + /> + ) : ( + + { + setServerCertificate({ + encoded_key: encodedValue || "", + id: serverCertificate?.id || "", + key: fileName || "", + cert: serverCertificate?.cert || "", + encoded_cert: + serverCertificate?.encoded_cert || "", + }); + cleanValidation("serverKey"); + }} + accept=".key,.pem" + id="serverKey" + name="serverKey" + label="Key" + value={serverCertificate?.key} + /> + { + setServerCertificate({ + encoded_key: + serverCertificate?.encoded_key || "", + id: serverCertificate?.id || "", + key: serverCertificate?.key || "", + cert: fileName || "", + encoded_cert: encodedValue || "", + }); + cleanValidation("serverCert"); + }} + accept=".cer,.crt,.cert,.pem" + id="serverCert" + name="serverCert" + label="Cert" + value={serverCertificate?.cert} + /> + + )} +
+
+
+ + +
+ + Mutual TLS authentication with MinIO + + {mTLSCertificateSecret ? ( + + + {mTLSCertificateSecret.name} + + + {mTLSCertificateSecret.domains && + mTLSCertificateSecret.domains.map((dom) => { + return
{dom}
; + })} +
+ + Expiry:  + + + + {mTLSCertificateSecret.expiry} + + + + } + onDelete={() => + removeCertificate(mTLSCertificateSecret) + } + /> + ) : ( + + { + setMTLSCertificate({ + encoded_key: encodedValue || "", + id: mTLSCertificate?.id || "", + key: fileName || "", + cert: mTLSCertificate?.cert || "", + encoded_cert: + mTLSCertificate?.encoded_cert || "", + }); + cleanValidation("clientKey"); + }} + accept=".key,.pem" + id="clientKey" + name="clientKey" + label="Key" + value={mTLSCertificate?.key} + /> + { + setMTLSCertificate({ + encoded_key: + mTLSCertificate?.encoded_key || "", + id: mTLSCertificate?.id || "", + key: mTLSCertificate?.key || "", + cert: fileName || "", + encoded_cert: encodedValue || "", + }); + cleanValidation("clientCert"); + }} + accept=".cer,.crt,.cert,.pem" + id="clientCert" + name="clientCert" + label="Cert" + value={mTLSCertificate?.cert} + /> + + )} +
+
+
+
+ )} + + + ) => + setImage(e.target.value) + } + label="Image" + placeholder="minio/kes:v0.17.6" + value={image} + /> + + + ) => + setReplicas(e.target.value) + } + label="Replicas" + value={replicas} + required + error={validationErrors["replicas"] || ""} + /> + + +
+ + SecurityContext for KES pods + + +
+
+ + ) => { + setSecurityContext({ + ...securityContext, + runAsUser: e.target.value, + }); + }} + label="Run As User" + value={securityContext.runAsUser} + required + error={ + validationErrors["kes_securityContext_runAsUser"] || + "" + } + min="0" + /> +
+
+ + ) => { + setSecurityContext({ + ...securityContext, + runAsGroup: e.target.value, + }); + }} + label="Run As Group" + value={securityContext.runAsGroup} + required + error={ + validationErrors[ + "kes_securityContext_runAsGroup" + ] || "" + } + min="0" + /> +
+
+ + ) => { + setSecurityContext({ + ...securityContext, + fsGroup: e.target.value, + }); + }} + label="FsGroup" + value={securityContext.fsGroup} + required + error={ + validationErrors["kes_securityContext_fsGroup"] || + "" + } + min="0" + /> +
+
+
+
+ +
+ { + const targetD = e.target; + const checked = targetD.checked; + setSecurityContext({ + ...securityContext, + runAsNonRoot: checked, + }); + }} + label={"Do not run as Root"} + /> +
+
+
+
+
+
+ )} + + + +
+
+ ); +}; + +const mapState = (state: AppState) => ({ + loadingTenant: state.tenants.tenantDetails.loadingTenant, + selectedTenant: state.tenants.tenantDetails.currentTenant, + tenant: state.tenants.tenantDetails.tenantInfo, +}); + +const mapDispatchToProps = { + setErrorSnackMessage, + setTenantDetailsLoad, +}; + +const connector = connect(mapState, mapDispatchToProps); + +export default withStyles(styles)(connector(TenantEncryption)); diff --git a/portal-ui/src/screens/Console/Tenants/types.ts b/portal-ui/src/screens/Console/Tenants/types.ts index 65e6329c1..62c8c77e0 100644 --- a/portal-ui/src/screens/Console/Tenants/types.ts +++ b/portal-ui/src/screens/Console/Tenants/types.ts @@ -14,7 +14,13 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . -import { IErasureCodeCalc } from "../../../common/types"; +import { + IAWSConfig, + IAzureConfig, + IErasureCodeCalc, + IGCPConfig, + IGemaltoCredentials, +} from "../../../common/types"; import { IResourcesSize, ITenant } from "./ListTenants/types"; import { KeyPair, Opts } from "./ListTenants/utils"; import { IntegrationConfiguration } from "./AddTenant/Steps/TenantResources/utils"; @@ -87,6 +93,58 @@ export interface ITenantSecurityResponse { customCertificates: ICustomCertificates; } +export interface IVaultTLS { + crt: ICertificateInfo; + ca: ICertificateInfo; +} + +export interface IVaultAppRole { + engine: string; + id: string; + secret: string; + retry: string; +} + +export interface IVaultStatus { + ping: string; +} + +export interface IVaultConfiguration { + endpoint: string; + engine: string; + namespace: string; + prefix: string; + approle: IVaultAppRole; + status: IVaultStatus; + tls: IVaultTLS; +} + +export interface IGemaltoTLS { + ca: ICertificateInfo; +} + +export interface IKeysecureConfiguration { + endpoint: string; + credentials: IGemaltoCredentials; + tls: IGemaltoTLS; +} +export interface IGemaltoConfiguration { + keysecure: IKeysecureConfiguration; +} + +export interface ITenantEncryptionResponse { + image: string; + replicas: string; + securityContext: ISecurityContext; + server: ICertificateInfo; + mtls_client: ICertificateInfo; + vault?: IVaultConfiguration; + aws?: IAWSConfig; + gemalto?: IGemaltoConfiguration; + gcp?: IGCPConfig; + azure?: IAzureConfig; +} + export interface ICreateTenant { page: number; validPages: string[]; diff --git a/portal-ui/src/utils/validationFunctions.ts b/portal-ui/src/utils/validationFunctions.ts index 5125a06a9..e4f611b77 100644 --- a/portal-ui/src/utils/validationFunctions.ts +++ b/portal-ui/src/utils/validationFunctions.ts @@ -31,6 +31,7 @@ export const commonFormValidation = (fieldsValidate: IValidation[]) => { if ( field.required && typeof field.value !== "undefined" && + field.value.trim && field.value.trim() === "" ) { returnErrors[field.fieldKey] = "Field cannot be empty"; @@ -40,6 +41,7 @@ export const commonFormValidation = (fieldsValidate: IValidation[]) => { if ( !field.required && typeof field.value !== "undefined" && + field.value.trim && field.value.trim() === "" ) { return; diff --git a/swagger-operator.yml b/swagger-operator.yml index 4c9896bd2..a83ba4445 100644 --- a/swagger-operator.yml +++ b/swagger-operator.yml @@ -844,6 +844,27 @@ paths: - OperatorAPI /namespaces/{namespace}/tenants/{tenant}/encryption: + delete: + summary: Tenant Delete Encryption + operationId: TenantDeleteEncryption + parameters: + - name: namespace + in: path + required: true + type: string + - name: tenant + in: path + required: true + type: string + responses: + 204: + description: A successful response. + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - OperatorAPI put: summary: Tenant Update Encryption operationId: TenantUpdateEncryption @@ -871,6 +892,30 @@ paths: tags: - OperatorAPI + get: + summary: Tenant Encryption Info + operationId: TenantEncryptionInfo + parameters: + - name: namespace + in: path + required: true + type: string + - name: tenant + in: path + required: true + type: string + responses: + 200: + description: A successful response. + schema: + $ref: "#/definitions/encryptionConfigurationResponse" + default: + description: Generic error response. + schema: + $ref: "#/definitions/error" + tags: + - OperatorAPI + /namespaces/{namespace}/tenants/{tenant}/yaml: get: summary: Get the Tenant YAML @@ -1622,6 +1667,10 @@ definitions: type: string replicas: type: string + secretsToBeDeleted: + type: array + items: + type: string server: type: object $ref: "#/definitions/keyPairConfiguration" @@ -1647,6 +1696,40 @@ definitions: type: object $ref: "#/definitions/securityContext" + encryptionConfigurationResponse: + allOf: + - $ref: "#/definitions/metadataFields" + - type: object + properties: + image: + type: string + replicas: + type: string + server: + type: object + $ref: "#/definitions/certificateInfo" + mtls_client: + type: object + $ref: "#/definitions/certificateInfo" + gemalto: + type: object + $ref: "#/definitions/gemaltoConfigurationResponse" + aws: + type: object + $ref: "#/definitions/awsConfiguration" + vault: + type: object + $ref: "#/definitions/vaultConfigurationResponse" + gcp: + type: object + $ref: "#/definitions/gcpConfiguration" + azure: + type: object + $ref: "#/definitions/azureConfiguration" + securityContext: + type: object + $ref: "#/definitions/securityContext" + vaultConfiguration: type: object required: @@ -1692,6 +1775,51 @@ definitions: ca: type: string + vaultConfigurationResponse: + type: object + required: + - endpoint + - approle + properties: + endpoint: + type: string + engine: + type: string + namespace: + type: string + prefix: + type: string + approle: + type: object + required: + - id + - secret + properties: + engine: + type: string + id: + type: string + secret: + type: string + retry: + type: integer + format: int64 + status: + type: object + properties: + ping: + type: integer + format: int64 + tls: + type: object + properties: + crt: + type: object + $ref: "#/definitions/certificateInfo" + ca: + type: object + $ref: "#/definitions/certificateInfo" + awsConfiguration: type: object required: @@ -1757,6 +1885,41 @@ definitions: ca: type: string + gemaltoConfigurationResponse: + type: object + required: + - keysecure + properties: + keysecure: + type: object + required: + - endpoint + - credentials + properties: + endpoint: + type: string + credentials: + type: object + required: + - token + - domain + properties: + token: + type: string + domain: + type: string + retry: + type: integer + format: int64 + tls: + type: object + required: + - ca + properties: + ca: + type: object + $ref: "#/definitions/certificateInfo" + gcpConfiguration: type: object required: