Adds Azure support for KES configuration in operator-ui (#1070)

Signed-off-by: Lenin Alevski <alevsk.8772@gmail.com>

Co-authored-by: Alex <33497058+bexsoft@users.noreply.github.com>
Co-authored-by: Daniel Valdivia <18384552+dvaldivia@users.noreply.github.com>
This commit is contained in:
Lenin Alevski
2021-09-21 20:56:07 -07:00
committed by GitHub
parent 137ff41be2
commit e6f4ac1e6c
10 changed files with 693 additions and 0 deletions

View File

@@ -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 <http://www.gnu.org/licenses/>.
//
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
}

View File

@@ -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 {

View File

@@ -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"

View File

@@ -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

View File

@@ -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 {

View File

@@ -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: {

View File

@@ -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" },
]}
/>
</Grid>
@@ -630,6 +674,63 @@ const Encryption = ({
</Grid>
</Fragment>
)}
{encryptionType === "azure" && (
<Fragment>
<Grid item xs={12}>
<InputBoxWrapper
id="azure_endpoint"
name="azure_endpoint"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("azureEndpoint", e.target.value);
cleanValidation("azure_endpoint");
}}
label="Endpoint"
value={azureEndpoint}
error={validationErrors["azure_endpoint"] || ""}
/>
</Grid>
<h5>Credentials</h5>
<Grid item xs={12}>
<InputBoxWrapper
id="azure_tenant_id"
name="azure_tenant_id"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("azureTenantID", e.target.value);
cleanValidation("azure_tenant_id");
}}
label="Tenant ID"
value={azureTenantID}
error={validationErrors["azure_tenant_id"] || ""}
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="azure_client_id"
name="azure_client_id"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("azureClientID", e.target.value);
cleanValidation("azure_client_id");
}}
label="Client ID"
value={azureClientID}
error={validationErrors["azure_client_id"] || ""}
/>
</Grid>
<Grid item xs={12}>
<InputBoxWrapper
id="azure_client_secret"
name="azure_client_secret"
onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
updateField("azureClientSecret", e.target.value);
cleanValidation("azure_client_secret");
}}
label="Client Secret"
value={azureClientSecret}
error={validationErrors["azure_client_secret"] || ""}
/>
</Grid>
</Fragment>
)}
{encryptionType === "gcp" && (
<Fragment>
<Grid item xs={12}>
@@ -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,

View File

@@ -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: "",

View File

@@ -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;

View File

@@ -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: