From e6f4ac1e6c9bf2d17638b6f5f73860afacb623cb Mon Sep 17 00:00:00 2001 From: Lenin Alevski Date: Tue, 21 Sep 2021 20:56:07 -0700 Subject: [PATCH] Adds Azure support for KES configuration in operator-ui (#1070) Signed-off-by: Lenin Alevski Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com> Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com> --- models/azure_configuration.go | 313 ++++++++++++++++++ models/encryption_configuration.go | 51 +++ operatorapi/embedded_spec.go | 133 ++++++++ operatorapi/operator_tenants_helper.go | 15 + pkg/kes/kes.go | 16 + .../Console/Tenants/AddTenant/AddTenant.tsx | 18 + .../Tenants/AddTenant/Steps/Encryption.tsx | 106 ++++++ .../src/screens/Console/Tenants/reducer.ts | 8 + .../src/screens/Console/Tenants/types.ts | 4 + swagger-operator.yml | 29 ++ 10 files changed, 693 insertions(+) create mode 100644 models/azure_configuration.go diff --git a/models/azure_configuration.go b/models/azure_configuration.go new file mode 100644 index 000000000..989ca58af --- /dev/null +++ b/models/azure_configuration.go @@ -0,0 +1,313 @@ +// 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" +) + +// AzureConfiguration azure configuration +// +// swagger:model azureConfiguration +type AzureConfiguration struct { + + // keyvault + // Required: true + Keyvault *AzureConfigurationKeyvault `json:"keyvault"` +} + +// Validate validates this azure configuration +func (m *AzureConfiguration) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateKeyvault(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *AzureConfiguration) validateKeyvault(formats strfmt.Registry) error { + + if err := validate.Required("keyvault", "body", m.Keyvault); err != nil { + return err + } + + if m.Keyvault != nil { + if err := m.Keyvault.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("keyvault") + } + return err + } + } + + return nil +} + +// ContextValidate validate this azure configuration based on the context it is used +func (m *AzureConfiguration) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateKeyvault(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *AzureConfiguration) contextValidateKeyvault(ctx context.Context, formats strfmt.Registry) error { + + if m.Keyvault != nil { + if err := m.Keyvault.ContextValidate(ctx, formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("keyvault") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *AzureConfiguration) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *AzureConfiguration) UnmarshalBinary(b []byte) error { + var res AzureConfiguration + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// AzureConfigurationKeyvault azure configuration keyvault +// +// swagger:model AzureConfigurationKeyvault +type AzureConfigurationKeyvault struct { + + // credentials + Credentials *AzureConfigurationKeyvaultCredentials `json:"credentials,omitempty"` + + // endpoint + // Required: true + Endpoint *string `json:"endpoint"` +} + +// Validate validates this azure configuration keyvault +func (m *AzureConfigurationKeyvault) 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 len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *AzureConfigurationKeyvault) validateCredentials(formats strfmt.Registry) error { + if swag.IsZero(m.Credentials) { // not required + return nil + } + + if m.Credentials != nil { + if err := m.Credentials.Validate(formats); err != nil { + if ve, ok := err.(*errors.Validation); ok { + return ve.ValidateName("keyvault" + "." + "credentials") + } + return err + } + } + + return nil +} + +func (m *AzureConfigurationKeyvault) validateEndpoint(formats strfmt.Registry) error { + + if err := validate.Required("keyvault"+"."+"endpoint", "body", m.Endpoint); err != nil { + return err + } + + return nil +} + +// ContextValidate validate this azure configuration keyvault based on the context it is used +func (m *AzureConfigurationKeyvault) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + var res []error + + if err := m.contextValidateCredentials(ctx, formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *AzureConfigurationKeyvault) 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("keyvault" + "." + "credentials") + } + return err + } + } + + return nil +} + +// MarshalBinary interface implementation +func (m *AzureConfigurationKeyvault) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *AzureConfigurationKeyvault) UnmarshalBinary(b []byte) error { + var res AzureConfigurationKeyvault + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} + +// AzureConfigurationKeyvaultCredentials azure configuration keyvault credentials +// +// swagger:model AzureConfigurationKeyvaultCredentials +type AzureConfigurationKeyvaultCredentials struct { + + // client id + // Required: true + ClientID *string `json:"client_id"` + + // client secret + // Required: true + ClientSecret *string `json:"client_secret"` + + // tenant id + // Required: true + TenantID *string `json:"tenant_id"` +} + +// Validate validates this azure configuration keyvault credentials +func (m *AzureConfigurationKeyvaultCredentials) Validate(formats strfmt.Registry) error { + var res []error + + if err := m.validateClientID(formats); err != nil { + res = append(res, err) + } + + if err := m.validateClientSecret(formats); err != nil { + res = append(res, err) + } + + if err := m.validateTenantID(formats); err != nil { + res = append(res, err) + } + + if len(res) > 0 { + return errors.CompositeValidationError(res...) + } + return nil +} + +func (m *AzureConfigurationKeyvaultCredentials) validateClientID(formats strfmt.Registry) error { + + if err := validate.Required("keyvault"+"."+"credentials"+"."+"client_id", "body", m.ClientID); err != nil { + return err + } + + return nil +} + +func (m *AzureConfigurationKeyvaultCredentials) validateClientSecret(formats strfmt.Registry) error { + + if err := validate.Required("keyvault"+"."+"credentials"+"."+"client_secret", "body", m.ClientSecret); err != nil { + return err + } + + return nil +} + +func (m *AzureConfigurationKeyvaultCredentials) validateTenantID(formats strfmt.Registry) error { + + if err := validate.Required("keyvault"+"."+"credentials"+"."+"tenant_id", "body", m.TenantID); err != nil { + return err + } + + return nil +} + +// ContextValidate validates this azure configuration keyvault credentials based on context it is used +func (m *AzureConfigurationKeyvaultCredentials) ContextValidate(ctx context.Context, formats strfmt.Registry) error { + return nil +} + +// MarshalBinary interface implementation +func (m *AzureConfigurationKeyvaultCredentials) MarshalBinary() ([]byte, error) { + if m == nil { + return nil, nil + } + return swag.WriteJSON(m) +} + +// UnmarshalBinary interface implementation +func (m *AzureConfigurationKeyvaultCredentials) UnmarshalBinary(b []byte) error { + var res AzureConfigurationKeyvaultCredentials + if err := swag.ReadJSON(b, &res); err != nil { + return err + } + *m = res + return nil +} diff --git a/models/encryption_configuration.go b/models/encryption_configuration.go index 7b85f6be8..b98f9906f 100644 --- a/models/encryption_configuration.go +++ b/models/encryption_configuration.go @@ -39,6 +39,9 @@ type EncryptionConfiguration struct { // aws Aws *AwsConfiguration `json:"aws,omitempty"` + // azure + Azure *AzureConfiguration `json:"azure,omitempty"` + // client Client *KeyPairConfiguration `json:"client,omitempty"` @@ -74,6 +77,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error { var dataAO1 struct { Aws *AwsConfiguration `json:"aws,omitempty"` + Azure *AzureConfiguration `json:"azure,omitempty"` + Client *KeyPairConfiguration `json:"client,omitempty"` Gcp *GcpConfiguration `json:"gcp,omitempty"` @@ -94,6 +99,8 @@ func (m *EncryptionConfiguration) UnmarshalJSON(raw []byte) error { m.Aws = dataAO1.Aws + m.Azure = dataAO1.Azure + m.Client = dataAO1.Client m.Gcp = dataAO1.Gcp @@ -123,6 +130,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) { var dataAO1 struct { Aws *AwsConfiguration `json:"aws,omitempty"` + Azure *AzureConfiguration `json:"azure,omitempty"` + Client *KeyPairConfiguration `json:"client,omitempty"` Gcp *GcpConfiguration `json:"gcp,omitempty"` @@ -140,6 +149,8 @@ func (m EncryptionConfiguration) MarshalJSON() ([]byte, error) { dataAO1.Aws = m.Aws + dataAO1.Azure = m.Azure + dataAO1.Client = m.Client dataAO1.Gcp = m.Gcp @@ -175,6 +186,10 @@ func (m *EncryptionConfiguration) Validate(formats strfmt.Registry) error { res = append(res, err) } + if err := m.validateAzure(formats); err != nil { + res = append(res, err) + } + if err := m.validateClient(formats); err != nil { res = append(res, err) } @@ -219,6 +234,24 @@ func (m *EncryptionConfiguration) validateAws(formats strfmt.Registry) error { return nil } +func (m *EncryptionConfiguration) 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") + } + return err + } + } + + return nil +} + func (m *EncryptionConfiguration) validateClient(formats strfmt.Registry) error { if swag.IsZero(m.Client) { // not required @@ -322,6 +355,10 @@ func (m *EncryptionConfiguration) ContextValidate(ctx context.Context, formats s res = append(res, err) } + if err := m.contextValidateAzure(ctx, formats); err != nil { + res = append(res, err) + } + if err := m.contextValidateClient(ctx, formats); err != nil { res = append(res, err) } @@ -362,6 +399,20 @@ func (m *EncryptionConfiguration) contextValidateAws(ctx context.Context, format return nil } +func (m *EncryptionConfiguration) 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") + } + return err + } + } + + return nil +} + func (m *EncryptionConfiguration) contextValidateClient(ctx context.Context, formats strfmt.Registry) error { if m.Client != nil { diff --git a/operatorapi/embedded_spec.go b/operatorapi/embedded_spec.go index 05502641f..f0d00e3d6 100644 --- a/operatorapi/embedded_spec.go +++ b/operatorapi/embedded_spec.go @@ -1465,6 +1465,44 @@ func init() { } } }, + "azureConfiguration": { + "type": "object", + "required": [ + "keyvault" + ], + "properties": { + "keyvault": { + "type": "object", + "required": [ + "endpoint" + ], + "properties": { + "credentials": { + "type": "object", + "required": [ + "tenant_id", + "client_id", + "client_secret" + ], + "properties": { + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "tenant_id": { + "type": "string" + } + } + }, + "endpoint": { + "type": "string" + } + } + } + } + }, "certificateInfo": { "type": "object", "properties": { @@ -1672,6 +1710,10 @@ func init() { "type": "object", "$ref": "#/definitions/awsConfiguration" }, + "azure": { + "type": "object", + "$ref": "#/definitions/azureConfiguration" + }, "client": { "type": "object", "$ref": "#/definitions/keyPairConfiguration" @@ -4567,6 +4609,55 @@ func init() { } } }, + "AzureConfigurationKeyvault": { + "type": "object", + "required": [ + "endpoint" + ], + "properties": { + "credentials": { + "type": "object", + "required": [ + "tenant_id", + "client_id", + "client_secret" + ], + "properties": { + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "tenant_id": { + "type": "string" + } + } + }, + "endpoint": { + "type": "string" + } + } + }, + "AzureConfigurationKeyvaultCredentials": { + "type": "object", + "required": [ + "tenant_id", + "client_id", + "client_secret" + ], + "properties": { + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "tenant_id": { + "type": "string" + } + } + }, "GcpConfigurationSecretmanager": { "type": "object", "required": [ @@ -5212,6 +5303,44 @@ func init() { } } }, + "azureConfiguration": { + "type": "object", + "required": [ + "keyvault" + ], + "properties": { + "keyvault": { + "type": "object", + "required": [ + "endpoint" + ], + "properties": { + "credentials": { + "type": "object", + "required": [ + "tenant_id", + "client_id", + "client_secret" + ], + "properties": { + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "tenant_id": { + "type": "string" + } + } + }, + "endpoint": { + "type": "string" + } + } + } + } + }, "certificateInfo": { "type": "object", "properties": { @@ -5419,6 +5548,10 @@ func init() { "type": "object", "$ref": "#/definitions/awsConfiguration" }, + "azure": { + "type": "object", + "$ref": "#/definitions/azureConfiguration" + }, "client": { "type": "object", "$ref": "#/definitions/keyPairConfiguration" diff --git a/operatorapi/operator_tenants_helper.go b/operatorapi/operator_tenants_helper.go index 7dd31c505..dda9c8b2d 100644 --- a/operatorapi/operator_tenants_helper.go +++ b/operatorapi/operator_tenants_helper.go @@ -498,6 +498,21 @@ func createOrReplaceKesConfigurationSecrets(ctx context.Context, clientSet K8sCl } } } + } else if encryptionCfg.Azure != nil { + // Initialize Azure + kesConfig.Keys.Azure = &kes.Azure{ + KeyVault: &kes.AzureKeyVault{}, + } + if encryptionCfg.Azure.Keyvault != nil { + kesConfig.Keys.Azure.KeyVault.Endpoint = *encryptionCfg.Azure.Keyvault.Endpoint + if encryptionCfg.Azure.Keyvault.Credentials != nil { + kesConfig.Keys.Azure.KeyVault.Credentials = &kes.AzureCredentials{ + TenantID: *encryptionCfg.Azure.Keyvault.Credentials.TenantID, + ClientID: *encryptionCfg.Azure.Keyvault.Credentials.ClientID, + ClientSecret: *encryptionCfg.Azure.Keyvault.Credentials.ClientSecret, + } + } + } } imm := true // if mTLSCertificates contains elements we create the kubernetes secret diff --git a/pkg/kes/kes.go b/pkg/kes/kes.go index 0055ee4ca..e9fff1b83 100644 --- a/pkg/kes/kes.go +++ b/pkg/kes/kes.go @@ -130,12 +130,28 @@ type Gcp struct { SecretManager *GcpSecretManager `yaml:"secretmanager,omitempty"` } +type AzureCredentials struct { + TenantID string `yaml:"tenant_id"` + ClientID string `yaml:"client_id"` + ClientSecret string `yaml:"client_secret"` +} + +type AzureKeyVault struct { + Endpoint string `yaml:"endpoint,omitempty"` + Credentials *AzureCredentials `yaml:"credentials,omitempty"` +} + +type Azure struct { + KeyVault *AzureKeyVault `yaml:"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"` } type ServerConfig struct { diff --git a/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx b/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx index 3a553a22e..be1336362 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/AddTenant.tsx @@ -157,6 +157,10 @@ const AddTenant = ({ const vaultSecret = fields.encryption.vaultSecret; const vaultRetry = fields.encryption.vaultRetry; const vaultPing = fields.encryption.vaultPing; + const azureEndpoint = fields.encryption.azureEndpoint; + const azureTenantID = fields.encryption.azureTenantID; + const azureClientID = fields.encryption.azureClientID; + const azureClientSecret = fields.encryption.azureClientSecret; const gcpProjectID = fields.encryption.gcpProjectID; const gcpEndpoint = fields.encryption.gcpEndpoint; const gcpClientEmail = fields.encryption.gcpClientEmail; @@ -406,6 +410,20 @@ const AddTenant = ({ }, }; break; + case "azure": + insertEncrypt = { + azure: { + keyvault: { + endpoint: azureEndpoint, + credentials: { + tenant_id: azureTenantID, + client_id: azureClientID, + client_secret: azureClientSecret, + }, + }, + }, + }; + break; case "gcp": insertEncrypt = { gcp: { 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 221c5f09a..9c05bda6e 100644 --- a/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Encryption.tsx +++ b/portal-ui/src/screens/Console/Tenants/AddTenant/Steps/Encryption.tsx @@ -74,6 +74,10 @@ interface IEncryptionProps { vaultSecret: string; vaultRetry: string; vaultPing: string; + azureEndpoint: string; + azureTenantID: string; + azureClientID: string; + azureClientSecret: string; gcpProjectID: string; gcpEndpoint: string; gcpClientEmail: string; @@ -132,6 +136,10 @@ const Encryption = ({ vaultSecret, vaultRetry, vaultPing, + azureEndpoint, + azureTenantID, + azureClientID, + azureClientSecret, gcpProjectID, gcpEndpoint, gcpClientEmail, @@ -293,6 +301,32 @@ const Encryption = ({ }, ]; } + + if (encryptionType === "azure") { + encryptionValidation = [ + ...encryptionValidation, + { + fieldKey: "azure_endpoint", + required: true, + value: azureEndpoint, + }, + { + fieldKey: "azure_tenant_id", + required: true, + value: azureTenantID, + }, + { + fieldKey: "azure_client_id", + required: true, + value: azureClientID, + }, + { + fieldKey: "azure_client_secret", + required: true, + value: azureClientSecret, + }, + ]; + } } const commonVal = commonFormValidation(encryptionValidation); @@ -318,6 +352,15 @@ const Encryption = ({ gemaltoDomain, gemaltoRetry, gcpProjectID, + gcpEndpoint, + gcpClientEmail, + gcpClientID, + gcpPrivateKeyID, + gcpPrivateKey, + azureEndpoint, + azureTenantID, + azureClientID, + azureClientSecret, isPageValid, enableAutoCert, enableCustomCerts, @@ -367,6 +410,7 @@ const Encryption = ({ { label: "AWS", value: "aws" }, { label: "Gemalto", value: "gemalto" }, { label: "GCP", value: "gcp" }, + { label: "Azure", value: "azure" }, ]} /> @@ -630,6 +674,63 @@ const Encryption = ({ )} + {encryptionType === "azure" && ( + + + ) => { + updateField("azureEndpoint", e.target.value); + cleanValidation("azure_endpoint"); + }} + label="Endpoint" + value={azureEndpoint} + error={validationErrors["azure_endpoint"] || ""} + /> + +
Credentials
+ + ) => { + updateField("azureTenantID", e.target.value); + cleanValidation("azure_tenant_id"); + }} + label="Tenant ID" + value={azureTenantID} + error={validationErrors["azure_tenant_id"] || ""} + /> + + + ) => { + updateField("azureClientID", e.target.value); + cleanValidation("azure_client_id"); + }} + label="Client ID" + value={azureClientID} + error={validationErrors["azure_client_id"] || ""} + /> + + + ) => { + updateField("azureClientSecret", e.target.value); + cleanValidation("azure_client_secret"); + }} + label="Client Secret" + value={azureClientSecret} + error={validationErrors["azure_client_secret"] || ""} + /> + +
+ )} {encryptionType === "gcp" && ( @@ -890,6 +991,11 @@ const mapState = (state: AppState) => ({ vaultSecret: state.tenants.createTenant.fields.encryption.vaultSecret, vaultRetry: state.tenants.createTenant.fields.encryption.vaultRetry, vaultPing: state.tenants.createTenant.fields.encryption.vaultPing, + azureEndpoint: state.tenants.createTenant.fields.encryption.azureEndpoint, + azureTenantID: state.tenants.createTenant.fields.encryption.azureTenantID, + azureClientID: state.tenants.createTenant.fields.encryption.azureClientID, + azureClientSecret: + state.tenants.createTenant.fields.encryption.azureClientSecret, gcpProjectID: state.tenants.createTenant.fields.encryption.gcpProjectID, gcpEndpoint: state.tenants.createTenant.fields.encryption.gcpEndpoint, gcpClientEmail: state.tenants.createTenant.fields.encryption.gcpClientEmail, diff --git a/portal-ui/src/screens/Console/Tenants/reducer.ts b/portal-ui/src/screens/Console/Tenants/reducer.ts index 3b21becf1..04e97c6cd 100644 --- a/portal-ui/src/screens/Console/Tenants/reducer.ts +++ b/portal-ui/src/screens/Console/Tenants/reducer.ts @@ -137,6 +137,10 @@ const initialState: ITenantState = { vaultSecret: "", vaultRetry: "0", vaultPing: "0", + azureEndpoint: "", + azureTenantID: "", + azureClientID: "", + azureClientSecret: "", gcpProjectID: "", gcpEndpoint: "", gcpClientEmail: "", @@ -606,6 +610,10 @@ export function tenantsReducer( vaultSecret: "", vaultRetry: "0", vaultPing: "0", + azureEndpoint: "", + azureTenantID: "", + azureClientID: "", + azureClientSecret: "", gcpProjectID: "", gcpEndpoint: "", gcpClientEmail: "", diff --git a/portal-ui/src/screens/Console/Tenants/types.ts b/portal-ui/src/screens/Console/Tenants/types.ts index 5e313bc23..e717e9084 100644 --- a/portal-ui/src/screens/Console/Tenants/types.ts +++ b/portal-ui/src/screens/Console/Tenants/types.ts @@ -201,6 +201,10 @@ export interface IEncryptionFields { vaultSecret: string; vaultRetry: string; vaultPing: string; + azureEndpoint: string; + azureTenantID: string; + azureClientID: string; + azureClientSecret: string; gcpProjectID: string; gcpEndpoint: string; gcpClientEmail: string; diff --git a/swagger-operator.yml b/swagger-operator.yml index 005d9cd18..7c951e916 100644 --- a/swagger-operator.yml +++ b/swagger-operator.yml @@ -1449,6 +1449,9 @@ definitions: gcp: type: object $ref: "#/definitions/gcpConfiguration" + azure: + type: object + $ref: "#/definitions/azureConfiguration" vaultConfiguration: type: object @@ -1586,6 +1589,32 @@ definitions: private_key: type: string + azureConfiguration: + type: object + required: + - keyvault + properties: + keyvault: + type: object + required: + - endpoint + properties: + endpoint: + type: string + credentials: + type: object + required: + - tenant_id + - client_id + - client_secret + properties: + tenant_id: + type: string + client_id: + type: string + client_secret: + type: string + createTenantResponse: type: object properties: