Skip to content

Commit

Permalink
[wip] nova novncproxy vencrypt support
Browse files Browse the repository at this point in the history
  • Loading branch information
stuggi committed Apr 24, 2024
1 parent e294896 commit 7628913
Show file tree
Hide file tree
Showing 15 changed files with 622 additions and 62 deletions.
27 changes: 23 additions & 4 deletions api/bases/nova.openstack.org_nova.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1085,10 +1085,29 @@ spec:
description: CaBundleSecretName - holding the CA certs
in a pre-created bundle file
type: string
secretName:
description: SecretName - holding the cert, key for
the service
type: string
service:
description: Service - Cert secret used for the nova
novnc service endpoint
properties:
secretName:
description: SecretName - holding the cert, key
for the service
type: string
type: object
vencrypt:
description: Vencrypt - cert secret containing the x509
certificate to be presented to the VNC server. The
CommonName field should match the primary hostname
of the controller node. If using a HA deployment,
the Organization field can also be configured to a
value that is common across all console proxy instances
in the deployment. https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration
properties:
secretName:
description: SecretName - holding the cert, key
for the service
type: string
type: object
type: object
type: object
nodeSelector:
Expand Down
25 changes: 22 additions & 3 deletions api/bases/nova.openstack.org_novacells.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -731,9 +731,28 @@ spec:
description: CaBundleSecretName - holding the CA certs in
a pre-created bundle file
type: string
secretName:
description: SecretName - holding the cert, key for the service
type: string
service:
description: Service - Cert secret used for the nova novnc
service endpoint
properties:
secretName:
description: SecretName - holding the cert, key for the
service
type: string
type: object
vencrypt:
description: Vencrypt - cert secret containing the x509 certificate
to be presented to the VNC server. The CommonName field
should match the primary hostname of the controller node.
If using a HA deployment, the Organization field can also
be configured to a value that is common across all console
proxy instances in the deployment. https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration
properties:
secretName:
description: SecretName - holding the cert, key for the
service
type: string
type: object
type: object
type: object
nodeSelector:
Expand Down
23 changes: 20 additions & 3 deletions api/bases/nova.openstack.org_novanovncproxies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,26 @@ spec:
description: CaBundleSecretName - holding the CA certs in a pre-created
bundle file
type: string
secretName:
description: SecretName - holding the cert, key for the service
type: string
service:
description: Service - Cert secret used for the nova novnc service
endpoint
properties:
secretName:
description: SecretName - holding the cert, key for the service
type: string
type: object
vencrypt:
description: Vencrypt - cert secret containing the x509 certificate
to be presented to the VNC server. The CommonName field should
match the primary hostname of the controller node. If using
a HA deployment, the Organization field can also be configured
to a value that is common across all console proxy instances
in the deployment. https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration
properties:
secretName:
description: SecretName - holding the cert, key for the service
type: string
type: object
type: object
required:
- cellDatabaseHostname
Expand Down
25 changes: 23 additions & 2 deletions api/v1beta1/novanovncproxy_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,28 @@ type NovaNoVNCProxyTemplate struct {
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec
// TLS - Parameters related to the TLS
TLS tls.SimpleService `json:"tls,omitempty"`
TLS TLSSection `json:"tls"`
}

// TLSSection defines the desired state of TLS configuration
type TLSSection struct {
// +kubebuilder:validation:optional
//+operator-sdk:csv:customresourcedefinitions:type=spec
// Service - Cert secret used for the nova novnc service endpoint
Service tls.GenericService `json:"service,omitempty"`

// +kubebuilder:validation:optional
//+operator-sdk:csv:customresourcedefinitions:type=spec
// Vencrypt - cert secret containing the x509 certificate to be presented to the VNC server.
// The CommonName field should match the primary hostname of the controller node. If using a HA deployment,
// the Organization field can also be configured to a value that is common across all console proxy instances in the deployment.
// https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration
Vencrypt tls.GenericService `json:"vencrypt,omitempty"`

// +kubebuilder:validation:optional
// +operator-sdk:csv:customresourcedefinitions:type=spec
// Secret containing CA bundle
tls.Ca `json:",inline"`
}

// VNCProxyOverrideSpec to override the generated manifest of several child resources.
Expand Down Expand Up @@ -135,7 +156,7 @@ type NovaNoVNCProxySpec struct {
// +kubebuilder:validation:Optional
// +operator-sdk:csv:customresourcedefinitions:type=spec
// TLS - Parameters related to the TLS
TLS tls.SimpleService `json:"tls,omitempty"`
TLS TLSSection `json:"tls"`

// +kubebuilder:validation:Required
// MemcachedInstance is the name of the Memcached CR that all nova service will use.
Expand Down
18 changes: 18 additions & 0 deletions api/v1beta1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

27 changes: 23 additions & 4 deletions config/crd/bases/nova.openstack.org_nova.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -1085,10 +1085,29 @@ spec:
description: CaBundleSecretName - holding the CA certs
in a pre-created bundle file
type: string
secretName:
description: SecretName - holding the cert, key for
the service
type: string
service:
description: Service - Cert secret used for the nova
novnc service endpoint
properties:
secretName:
description: SecretName - holding the cert, key
for the service
type: string
type: object
vencrypt:
description: Vencrypt - cert secret containing the x509
certificate to be presented to the VNC server. The
CommonName field should match the primary hostname
of the controller node. If using a HA deployment,
the Organization field can also be configured to a
value that is common across all console proxy instances
in the deployment. https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration
properties:
secretName:
description: SecretName - holding the cert, key
for the service
type: string
type: object
type: object
type: object
nodeSelector:
Expand Down
25 changes: 22 additions & 3 deletions config/crd/bases/nova.openstack.org_novacells.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -731,9 +731,28 @@ spec:
description: CaBundleSecretName - holding the CA certs in
a pre-created bundle file
type: string
secretName:
description: SecretName - holding the cert, key for the service
type: string
service:
description: Service - Cert secret used for the nova novnc
service endpoint
properties:
secretName:
description: SecretName - holding the cert, key for the
service
type: string
type: object
vencrypt:
description: Vencrypt - cert secret containing the x509 certificate
to be presented to the VNC server. The CommonName field
should match the primary hostname of the controller node.
If using a HA deployment, the Organization field can also
be configured to a value that is common across all console
proxy instances in the deployment. https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration
properties:
secretName:
description: SecretName - holding the cert, key for the
service
type: string
type: object
type: object
type: object
nodeSelector:
Expand Down
23 changes: 20 additions & 3 deletions config/crd/bases/nova.openstack.org_novanovncproxies.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -336,9 +336,26 @@ spec:
description: CaBundleSecretName - holding the CA certs in a pre-created
bundle file
type: string
secretName:
description: SecretName - holding the cert, key for the service
type: string
service:
description: Service - Cert secret used for the nova novnc service
endpoint
properties:
secretName:
description: SecretName - holding the cert, key for the service
type: string
type: object
vencrypt:
description: Vencrypt - cert secret containing the x509 certificate
to be presented to the VNC server. The CommonName field should
match the primary hostname of the controller node. If using
a HA deployment, the Organization field can also be configured
to a value that is common across all console proxy instances
in the deployment. https://docs.openstack.org/nova/latest/admin/remote-console-access.html#novnc-proxy-server-configuration
properties:
secretName:
description: SecretName - holding the cert, key for the service
type: string
type: object
type: object
required:
- cellDatabaseHostname
Expand Down
13 changes: 7 additions & 6 deletions controllers/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,13 @@ const (
TransportURLSelector = "transport_url"

// fields to index to reconcile when change
passwordSecretField = ".spec.secret"
caBundleSecretNameField = ".spec.tls.caBundleSecretName"
tlsAPIInternalField = ".spec.tls.api.internal.secretName"
tlsAPIPublicField = ".spec.tls.api.public.secretName"
tlsMetadataField = ".spec.tls.secretName"
tlsNoVNCProxyField = ".spec.tls.secretName"
passwordSecretField = ".spec.secret"
caBundleSecretNameField = ".spec.tls.caBundleSecretName"
tlsAPIInternalField = ".spec.tls.api.internal.secretName"
tlsAPIPublicField = ".spec.tls.api.public.secretName"
tlsMetadataField = ".spec.tls.secretName"
tlsNoVNCProxyServiceField = ".spec.tls.service.secretName"
tlsNoVNCProxyVencryptField = ".spec.tls.vencrypt.secretName"

// NovaAPIDatabaseName is the name of the DB schema created for the
// top level nova DB
Expand Down
54 changes: 45 additions & 9 deletions controllers/novanovncproxy_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,9 @@ func (r *NovaNoVNCProxyReconciler) Reconcile(ctx context.Context, req ctrl.Reque
}
}

// Validate metadata service cert secret
if instance.Spec.TLS.Enabled() {
hash, ctrlResult, err := instance.Spec.TLS.ValidateCertSecret(ctx, h, instance.Namespace)
// Validate the service cert secret
if instance.Spec.TLS.Service.Enabled() {
hash, ctrlResult, err := instance.Spec.TLS.Service.ValidateCertSecret(ctx, h, instance.Namespace)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.TLSInputReadyCondition,
Expand All @@ -235,6 +235,23 @@ func (r *NovaNoVNCProxyReconciler) Reconcile(ctx context.Context, req ctrl.Reque
hashes[tls.TLSHashName] = env.SetValue(hash)
}

// Validate the Vencrypt cert secret
if instance.Spec.TLS.Vencrypt.Enabled() {
hash, ctrlResult, err := instance.Spec.TLS.Vencrypt.ValidateCertSecret(ctx, h, instance.Namespace)
if err != nil {
instance.Status.Conditions.Set(condition.FalseCondition(
condition.TLSInputReadyCondition,
condition.ErrorReason,
condition.SeverityWarning,
condition.TLSInputErrorMessage,
err.Error()))
return ctrl.Result{}, err
} else if (ctrlResult != ctrl.Result{}) {
return ctrlResult, nil
}
hashes[novncproxy.VencryptName] = env.SetValue(hash)
}

// all cert input checks out so report InputReady
instance.Status.Conditions.MarkTrue(condition.TLSInputReadyCondition, condition.InputReadyMessage)

Expand Down Expand Up @@ -414,11 +431,17 @@ func (r *NovaNoVNCProxyReconciler) generateConfigs(
"MemcachedServersWithInet": memcachedInstance.GetMemcachedServerListWithInetString(),
"MemcachedTLS": memcachedInstance.GetMemcachedTLSSupport(),
}
if instance.Spec.TLS.GenericService.Enabled() {
if instance.Spec.TLS.Service.Enabled() {
templateParameters["SSLCertificateFile"] = fmt.Sprintf("/etc/pki/tls/certs/%s.crt", novncproxy.ServiceName)
templateParameters["SSLCertificateKeyFile"] = fmt.Sprintf("/etc/pki/tls/private/%s.key", novncproxy.ServiceName)
}

if instance.Spec.TLS.Vencrypt.Enabled() {
templateParameters["VencryptClientKey"] = "/etc/pki/nova-novncproxy/client-key.pem"
templateParameters["VencryptClientCert"] = "/etc/pki/nova-novncproxy/client-cert.pem"
templateParameters["VencryptCACerts"] = "/etc/pki/nova-novncproxy/ca-cert.pem"
}

var tlsCfg *tls.Service
if instance.Spec.TLS.CaBundleSecretName != "" {
tlsCfg = &tls.Service{}
Expand Down Expand Up @@ -697,7 +720,8 @@ var (
noVNCProxyWatchFields = []string{
passwordSecretField,
caBundleSecretNameField,
tlsNoVNCProxyField,
tlsNoVNCProxyServiceField,
tlsNoVNCProxyVencryptField,
}
)

Expand Down Expand Up @@ -755,14 +779,26 @@ func (r *NovaNoVNCProxyReconciler) SetupWithManager(mgr ctrl.Manager) error {
return err
}

// index tlsNoVNCProxyField
if err := mgr.GetFieldIndexer().IndexField(context.Background(), &novav1.NovaNoVNCProxy{}, tlsNoVNCProxyField, func(rawObj client.Object) []string {
// index service cert secret tlsNoVNCProxyField
if err := mgr.GetFieldIndexer().IndexField(context.Background(), &novav1.NovaNoVNCProxy{}, tlsNoVNCProxyServiceField, func(rawObj client.Object) []string {
// Extract the secret name from the spec, if one is provided
cr := rawObj.(*novav1.NovaNoVNCProxy)
if cr.Spec.TLS.Service.SecretName == nil {
return nil
}
return []string{*cr.Spec.TLS.Service.SecretName}
}); err != nil {
return err
}

// index vencrypt cert secret tlsNoVNCProxyField
if err := mgr.GetFieldIndexer().IndexField(context.Background(), &novav1.NovaNoVNCProxy{}, tlsNoVNCProxyVencryptField, func(rawObj client.Object) []string {
// Extract the secret name from the spec, if one is provided
cr := rawObj.(*novav1.NovaNoVNCProxy)
if cr.Spec.TLS.SecretName == nil {
if cr.Spec.TLS.Vencrypt.SecretName == nil {
return nil
}
return []string{*cr.Spec.TLS.SecretName}
return []string{*cr.Spec.TLS.Vencrypt.SecretName}
}); err != nil {
return err
}
Expand Down
5 changes: 3 additions & 2 deletions pkg/novncproxy/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const (
//NoVNCProxyPort - The port the nova-noVNCProxyPort service is exposed on
NoVNCProxyPort = 6080
// ServiceName - The name of the service exposed to k8s
ServiceName = "nova-novncproxy"
Host = "::0"
ServiceName = "nova-novncproxy"
Host = "::0"
VencryptName = "vencrypt"
)
Loading

0 comments on commit 7628913

Please sign in to comment.