diff --git a/cmd/osm-bootstrap/crds/config_mesh_root_certificate.yaml b/cmd/osm-bootstrap/crds/config_mesh_root_certificate.yaml index e9914039c6..f94344e0ab 100644 --- a/cmd/osm-bootstrap/crds/config_mesh_root_certificate.yaml +++ b/cmd/osm-bootstrap/crds/config_mesh_root_certificate.yaml @@ -106,16 +106,52 @@ spec: type: string token: description: Token used by the mesh control plane - type: string + type: object + required: + - secretKeyRef + properties: + secretKeyRef: + description: Reference to the kubernetes secret storing the vault token + type: object + required: + - name + - key + - namespace + properties: + name: + description: Name of the kubernetes secret + type: string + key: + description: Kubernetes secret key + type: string + namespace: + description: Namespace of the kubernetes secret + type: string tresor: description: Tresor provider configuration type: object required: - - secretName + - ca properties: - secretName: - description: Name of the kubernetes secret storing the root certificate - type: string + ca: + description: The root certificate used by Tresor + type: object + required: + - secretRef + properties: + secretRef: + description: Reference to the kubernetes secret storing the root certificate + type: object + required: + - name + - namespace + properties: + name: + description: Name of the kubernetes secret + type: string + namespace: + description: Namespace of the kubernetes secret + type: string oneOf: - required: ['certManager'] - required: ['vault'] diff --git a/pkg/apis/config/v1alpha2/meshrootcertificate.go b/pkg/apis/config/v1alpha2/meshrootcertificate.go index d345f17a28..93a4be49a6 100644 --- a/pkg/apis/config/v1alpha2/meshrootcertificate.go +++ b/pkg/apis/config/v1alpha2/meshrootcertificate.go @@ -1,6 +1,7 @@ package v1alpha2 import ( + corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -75,15 +76,39 @@ type VaultProviderSpec struct { // Protocol specifies the protocol for connections to Vault Protocol string `json:"protocol"` - // Token specifies the name of the token to be used by mesh control plane + // Token specifies the configuration of the token to be used by mesh control plane // to connect to Vault - Token string `json:"token"` + Token VaultTokenSpec `json:"token"` +} + +// VaultTokenSpec defines the configuration of the Vault token +type VaultTokenSpec struct { + // SecretKeyRef specifies the secret in which the Vault token is stored + SecretKeyRef SecretKeyReferenceSpec `json:"secretKeyRef"` +} + +// SecretKeyReferenceSpec defines the configuration of the secret reference +type SecretKeyReferenceSpec struct { + // Name specifies the name of the secret in which the Vault token is stored + Name string `json:"name"` + + // Key specifies the key whose value is the Vault token + Key string `json:"key"` + + // Namespace specifies the namespace of the secret in which the Vault token is stored + Namespace string `json:"namespace"` } // TresorProviderSpec defines the configuration of the Tresor provider type TresorProviderSpec struct { - // SecretName specifies the name of the secret storing the root certificate - SecretName string `json:"secretName"` + // CA specifies Tresor's ca configuration + CA TresorCASpec `json:"ca"` +} + +// TresorCASpec defines the configuration of Tresor's root certificate +type TresorCASpec struct { + // SecretRef specifies the secret in which the root certificate is stored + SecretRef corev1.SecretReference `json:"secretRef"` } // MeshRootCertificateStatus defines the status of the MeshRootCertificate resource diff --git a/pkg/apis/config/v1alpha2/zz_generated.deepcopy.go b/pkg/apis/config/v1alpha2/zz_generated.deepcopy.go index ce28901e80..4738379440 100644 --- a/pkg/apis/config/v1alpha2/zz_generated.deepcopy.go +++ b/pkg/apis/config/v1alpha2/zz_generated.deepcopy.go @@ -454,6 +454,22 @@ func (in *ProviderSpec) DeepCopy() *ProviderSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SecretKeyReferenceSpec) DeepCopyInto(out *SecretKeyReferenceSpec) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SecretKeyReferenceSpec. +func (in *SecretKeyReferenceSpec) DeepCopy() *SecretKeyReferenceSpec { + if in == nil { + return nil + } + out := new(SecretKeyReferenceSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SidecarSpec) DeepCopyInto(out *SidecarSpec) { *out = *in @@ -539,9 +555,27 @@ func (in *TrafficSpec) DeepCopy() *TrafficSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *TresorCASpec) DeepCopyInto(out *TresorCASpec) { + *out = *in + out.SecretRef = in.SecretRef + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new TresorCASpec. +func (in *TresorCASpec) DeepCopy() *TresorCASpec { + if in == nil { + return nil + } + out := new(TresorCASpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *TresorProviderSpec) DeepCopyInto(out *TresorProviderSpec) { *out = *in + out.CA = in.CA return } @@ -558,6 +592,7 @@ func (in *TresorProviderSpec) DeepCopy() *TresorProviderSpec { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *VaultProviderSpec) DeepCopyInto(out *VaultProviderSpec) { *out = *in + out.Token = in.Token return } @@ -570,3 +605,20 @@ func (in *VaultProviderSpec) DeepCopy() *VaultProviderSpec { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *VaultTokenSpec) DeepCopyInto(out *VaultTokenSpec) { + *out = *in + out.SecretKeyRef = in.SecretKeyRef + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new VaultTokenSpec. +func (in *VaultTokenSpec) DeepCopy() *VaultTokenSpec { + if in == nil { + return nil + } + out := new(VaultTokenSpec) + in.DeepCopyInto(out) + return out +} diff --git a/pkg/certificate/providers/config.go b/pkg/certificate/providers/config.go index 2543453a75..bdb19d4cd4 100644 --- a/pkg/certificate/providers/config.go +++ b/pkg/certificate/providers/config.go @@ -63,6 +63,11 @@ func NewCertificateManager(kubeClient kubernetes.Interface, kubeConfig *rest.Con }, } + // TODO(#4745): Remove after deprecating the osm.vault.token option. + if vaultOption, ok := options.(VaultOptions); ok { + mrcClient.MRCProviderGenerator.DefaultVaultToken = vaultOption.VaultToken + } + return certificate.NewManager(mrcClient, cfg.GetServiceCertValidityPeriod(), msgBroker) } @@ -99,7 +104,7 @@ func (c *MRCProviderGenerator) getTresorOSMCertificateManager(mrc *v1alpha2.Mesh return nil, errors.New("Root cert does not have a private key") } - rootCert, err = k8s.GetCertificateFromSecret(mrc.Namespace, mrc.Spec.Provider.Tresor.SecretName, rootCert, c.kubeClient) + rootCert, err = k8s.GetCertificateFromSecret(mrc.Namespace, mrc.Spec.Provider.Tresor.CA.SecretRef.Name, rootCert, c.kubeClient) if err != nil { return nil, fmt.Errorf("Failed to synchronize certificate on Secrets API : %w", err) } @@ -125,9 +130,10 @@ func (c *MRCProviderGenerator) getHashiVaultOSMCertificateManager(mrc *v1alpha2. // A Vault address would have the following shape: "http://vault.default.svc.cluster.local:8200" vaultAddr := fmt.Sprintf("%s://%s:%d", provider.Protocol, provider.Host, provider.Port) + // TODO(#4502): If the DefaultVaultToken is empty, query the mrc.provider.vault.token.secretRef. vaultClient, err := vault.New( vaultAddr, - provider.Token, + c.DefaultVaultToken, provider.Role, ) if err != nil { diff --git a/pkg/certificate/providers/options.go b/pkg/certificate/providers/options.go index 22da47e198..ba78e9eec4 100644 --- a/pkg/certificate/providers/options.go +++ b/pkg/certificate/providers/options.go @@ -4,9 +4,13 @@ import ( "errors" "fmt" + corev1 "k8s.io/api/core/v1" + "github.com/openservicemesh/osm/pkg/apis/config/v1alpha2" ) +const vaultTokenSecretName = "osm-vault-token" // #nosec G101: Potential hardcoded credentials + // Validate validates the options for Tresor certificate provider func (options TresorOptions) Validate() error { if options.SecretName == "" { @@ -19,7 +23,11 @@ func (options TresorOptions) Validate() error { func (options TresorOptions) AsProviderSpec() v1alpha2.ProviderSpec { return v1alpha2.ProviderSpec{ Tresor: &v1alpha2.TresorProviderSpec{ - SecretName: options.SecretName, + CA: v1alpha2.TresorCASpec{ + SecretRef: corev1.SecretReference{ + Name: options.SecretName, + }, + }, }, } } @@ -51,9 +59,13 @@ func (options VaultOptions) AsProviderSpec() v1alpha2.ProviderSpec { Vault: &v1alpha2.VaultProviderSpec{ Protocol: options.VaultProtocol, Host: options.VaultHost, - Token: options.VaultToken, - Role: options.VaultRole, - Port: options.VaultPort, + Token: v1alpha2.VaultTokenSpec{ + SecretKeyRef: v1alpha2.SecretKeyReferenceSpec{ + Name: vaultTokenSecretName, + }, + }, + Role: options.VaultRole, + Port: options.VaultPort, }, } } diff --git a/pkg/certificate/providers/types.go b/pkg/certificate/providers/types.go index c68bab90a9..af8806ae38 100644 --- a/pkg/certificate/providers/types.go +++ b/pkg/certificate/providers/types.go @@ -51,7 +51,7 @@ type TresorOptions struct { type VaultOptions struct { VaultProtocol string VaultHost string - VaultToken string + VaultToken string // TODO(#4745): Remove after deprecating the osm.vault.token option. Replace with VaultTokenSecretName VaultRole string VaultPort int } @@ -78,4 +78,7 @@ type MRCProviderGenerator struct { // TODO(#4502): move these to the compat client once we have added these fields to the MRC. KeyBitSize int + + // TODO(#4745): Remove after deprecating the osm.vault.token option. + DefaultVaultToken string }