Skip to content

Commit faa0f3c

Browse files
Merge pull request openstack-k8s-operators#1410 from auniyal61/novncproxy-cert-cleanup
Novncproxy cert cleanup
2 parents f06564d + 2e665b6 commit faa0f3c

File tree

5 files changed

+310
-50
lines changed

5 files changed

+310
-50
lines changed

apis/core/v1beta1/conditions.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,9 @@ const (
149149

150150
// OpenStackControlPlaneInstanceHaCMReadyCondition Status=True condition which indicates if InstanceHa CM is ready
151151
OpenStackControlPlaneInstanceHaCMReadyCondition condition.Type = "OpenStackControlPlaneInstanceHaCMReadyCondition"
152+
153+
// OpenStackControlPlaneCertCleanupReadyCondition Status=True condition which indicates global certification cleanup is Ready
154+
OpenStackControlPlaneCertCleanupReadyCondition condition.Type = "OpenStackControlPlaneCertCleanupReadyCondition"
152155
)
153156

154157
// Common Messages used by API objects.
@@ -280,6 +283,9 @@ const (
280283
// OpenStackControlPlaneNovaReadyErrorMessage
281284
OpenStackControlPlaneNovaReadyErrorMessage = "OpenStackControlPlane Nova error occured %s"
282285

286+
// OpenStackControlPlaneCertCleanupReadyErrorMessage
287+
OpenStackControlPlaneCertCleanupReadyErrorMessage = "OpenStackControlPlane Cert cleanup error occured %s"
288+
283289
// OpenStackControlPlaneHeatReadyInitMessage
284290
OpenStackControlPlaneHeatReadyInitMessage = "OpenStackControlPlane Heat not started"
285291

controllers/core/openstackcontrolplane_controller.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,6 +528,19 @@ func (r *OpenStackControlPlaneReconciler) reconcileNormal(ctx context.Context, i
528528
return ctrlResult, nil
529529
}
530530

531+
ctrlResult, errs := openstack.DeleteCertsAndRoutes(ctx, instance, helper)
532+
if errs != nil {
533+
instance.Status.Conditions.Set(condition.FalseCondition(
534+
corev1beta1.OpenStackControlPlaneCertCleanupReadyCondition,
535+
condition.ErrorReason,
536+
condition.SeverityWarning,
537+
corev1beta1.OpenStackControlPlaneCertCleanupReadyErrorMessage,
538+
errs))
539+
return ctrlResult, errs
540+
}
541+
542+
instance.Status.Conditions.Remove(corev1beta1.OpenStackControlPlaneCertCleanupReadyCondition)
543+
531544
return ctrl.Result{}, nil
532545
}
533546

pkg/openstack/common.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@ package openstack
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
7+
"strings"
68
"time"
79

810
certmgrv1 "github.com/cert-manager/cert-manager/pkg/apis/certmanager/v1"
@@ -22,6 +24,7 @@ import (
2224
"github.com/openstack-k8s-operators/lib-common/modules/common/clusterdns"
2325
"github.com/openstack-k8s-operators/lib-common/modules/common/condition"
2426
"github.com/openstack-k8s-operators/lib-common/modules/common/helper"
27+
"github.com/openstack-k8s-operators/lib-common/modules/common/object"
2528
"github.com/openstack-k8s-operators/lib-common/modules/common/route"
2629
"github.com/openstack-k8s-operators/lib-common/modules/common/secret"
2730
"github.com/openstack-k8s-operators/lib-common/modules/common/service"
@@ -33,6 +36,9 @@ import (
3336
novav1 "github.com/openstack-k8s-operators/nova-operator/api/v1beta1"
3437
octaviav1 "github.com/openstack-k8s-operators/octavia-operator/api/v1beta1"
3538
corev1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1"
39+
40+
// corev1 "k8s.io/api/core/v1"
41+
corev1beta1 "github.com/openstack-k8s-operators/openstack-operator/apis/core/v1beta1"
3642
ovnv1 "github.com/openstack-k8s-operators/ovn-operator/api/v1beta1"
3743
placementv1 "github.com/openstack-k8s-operators/placement-operator/api/v1beta1"
3844
swiftv1 "github.com/openstack-k8s-operators/swift-operator/api/v1beta1"
@@ -805,6 +811,15 @@ func hasCertInOverrideSpec(overrideSpec route.OverrideSpec) bool {
805811
overrideSpec.Spec.TLS.Key != ""
806812
}
807813

814+
func serviceExists(route string, services *k8s_corev1.ServiceList) bool {
815+
for _, svc := range services.Items {
816+
if svc.Name == route {
817+
return true
818+
}
819+
}
820+
return false
821+
}
822+
808823
func DeleteCertificate(
809824
ctx context.Context,
810825
helper *helper.Helper,
@@ -824,3 +839,77 @@ func DeleteCertificate(
824839
helper.GetLogger().Info(fmt.Sprintf("Deleting cert %s", certName))
825840
return cert.Delete(ctx, helper)
826841
}
842+
843+
func DeleteCertsAndRoutes(
844+
ctx context.Context,
845+
instance *corev1beta1.OpenStackControlPlane,
846+
helper *helper.Helper,
847+
) (ctrl.Result, error) {
848+
849+
log := GetLogger(ctx)
850+
851+
// Retrieve all routes, certs and services in the namespace
852+
routes, err := GetRoutesListWithLabel(ctx, helper, instance.Namespace, nil)
853+
if err != nil {
854+
return ctrl.Result{}, fmt.Errorf("could not get routes: %w", err)
855+
}
856+
857+
certs := &certmgrv1.CertificateList{}
858+
if err := helper.GetClient().List(ctx, certs, client.InNamespace(instance.Namespace)); err != nil {
859+
return ctrl.Result{}, fmt.Errorf("could not get certificates: %w", err)
860+
}
861+
862+
services := &k8s_corev1.ServiceList{}
863+
if err := helper.GetClient().List(ctx, services, client.InNamespace(instance.Namespace)); err != nil {
864+
return ctrl.Result{}, fmt.Errorf("could not get services: %w", err)
865+
}
866+
867+
var delErrs []error
868+
for _, route := range routes.Items {
869+
870+
if !object.CheckOwnerRefExist(instance.GetUID(), route.OwnerReferences) {
871+
continue
872+
}
873+
874+
if serviceExists(route.Spec.To.Name, services) {
875+
continue
876+
}
877+
878+
// Delete certs by service and route-name
879+
for _, cert := range certs.Items {
880+
if _, ok := cert.Labels[serviceCertSelector]; ok && strings.Contains(cert.Name, route.Name) {
881+
if object.CheckOwnerRefExist(instance.GetUID(), cert.OwnerReferences) {
882+
log.Info("Deleting certificate", ":", cert.Name)
883+
err := DeleteCertificate(ctx, helper, instance.Namespace, cert.Name)
884+
if err != nil {
885+
delErrs = append(delErrs, fmt.Errorf("cert deletion for '%s' failed, because: %w", cert.Name, err))
886+
}
887+
}
888+
}
889+
890+
// NOTE(auniyal): This is specifically to cleanup novncproxy certs, others service certs do not use commonName as of now
891+
// TODO: this can be removed once we can map service, route and certs with `osctlplane-service` label
892+
if strings.Contains(cert.Spec.CommonName, route.Name) {
893+
if object.CheckOwnerRefExist(instance.GetUID(), cert.OwnerReferences) {
894+
log.Info("Deleting certificate", ":", cert.Name)
895+
err := DeleteCertificate(ctx, helper, instance.Namespace, cert.Name)
896+
if err != nil {
897+
delErrs = append(delErrs, fmt.Errorf("cert deletion for '%s' failed, because: %w", cert.Name, err))
898+
}
899+
}
900+
}
901+
}
902+
903+
log.Info("Deleting route", ":", route.Name)
904+
_, err := EnsureDeleted(ctx, helper, &route)
905+
if err != nil {
906+
delErrs = append(delErrs, fmt.Errorf("route deletion for '%s' failed, because: %w", route.Name, err))
907+
}
908+
}
909+
910+
if len(delErrs) > 0 {
911+
return ctrl.Result{}, errors.Join(delErrs...)
912+
}
913+
914+
return ctrl.Result{}, nil
915+
}

tests/functional/ctlplane/base_test.go

Lines changed: 56 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -44,47 +44,50 @@ import (
4444
)
4545

4646
type Names struct {
47-
Namespace string
48-
OpenStackControlplaneName types.NamespacedName
49-
OpenStackVersionName types.NamespacedName
50-
KeystoneAPIName types.NamespacedName
51-
MemcachedName types.NamespacedName
52-
MemcachedCertName types.NamespacedName
53-
CinderName types.NamespacedName
54-
ManilaName types.NamespacedName
55-
GlanceName types.NamespacedName
56-
NeutronName types.NamespacedName
57-
HorizonName types.NamespacedName
58-
HeatName types.NamespacedName
59-
TelemetryName types.NamespacedName
60-
DBName types.NamespacedName
61-
DBCertName types.NamespacedName
62-
DBCell1Name types.NamespacedName
63-
DBCell1CertName types.NamespacedName
64-
RabbitMQName types.NamespacedName
65-
RabbitMQCertName types.NamespacedName
66-
RabbitMQCell1Name types.NamespacedName
67-
RabbitMQCell1CertName types.NamespacedName
68-
ServiceAccountName types.NamespacedName
69-
RoleName types.NamespacedName
70-
RoleBindingName types.NamespacedName
71-
RootCAPublicName types.NamespacedName
72-
RootCAInternalName types.NamespacedName
73-
RootCAOvnName types.NamespacedName
74-
RootCALibvirtName types.NamespacedName
75-
SelfSignedIssuerName types.NamespacedName
76-
CustomIssuerName types.NamespacedName
77-
CustomServiceCertSecretName types.NamespacedName
78-
CABundleName types.NamespacedName
79-
OpenStackClientName types.NamespacedName
80-
OVNNorthdName types.NamespacedName
81-
OVNNorthdCertName types.NamespacedName
82-
OVNControllerName types.NamespacedName
83-
OVNControllerCertName types.NamespacedName
84-
OVNDbServerNBName types.NamespacedName
85-
OVNDbServerSBName types.NamespacedName
86-
NeutronOVNCertName types.NamespacedName
87-
OpenStackTopology []types.NamespacedName
47+
Namespace string
48+
OpenStackControlplaneName types.NamespacedName
49+
OpenStackVersionName types.NamespacedName
50+
KeystoneAPIName types.NamespacedName
51+
MemcachedName types.NamespacedName
52+
MemcachedCertName types.NamespacedName
53+
CinderName types.NamespacedName
54+
ManilaName types.NamespacedName
55+
GlanceName types.NamespacedName
56+
NeutronName types.NamespacedName
57+
HorizonName types.NamespacedName
58+
HeatName types.NamespacedName
59+
TelemetryName types.NamespacedName
60+
DBName types.NamespacedName
61+
DBCertName types.NamespacedName
62+
DBCell1Name types.NamespacedName
63+
DBCell1CertName types.NamespacedName
64+
RabbitMQName types.NamespacedName
65+
RabbitMQCertName types.NamespacedName
66+
RabbitMQCell1Name types.NamespacedName
67+
RabbitMQCell1CertName types.NamespacedName
68+
NoVNCProxyCell1CertPublicRouteName types.NamespacedName
69+
NoVNCProxyCell1CertPublicSvcName types.NamespacedName
70+
NoVNCProxyCell1CertVencryptName types.NamespacedName
71+
ServiceAccountName types.NamespacedName
72+
RoleName types.NamespacedName
73+
RoleBindingName types.NamespacedName
74+
RootCAPublicName types.NamespacedName
75+
RootCAInternalName types.NamespacedName
76+
RootCAOvnName types.NamespacedName
77+
RootCALibvirtName types.NamespacedName
78+
SelfSignedIssuerName types.NamespacedName
79+
CustomIssuerName types.NamespacedName
80+
CustomServiceCertSecretName types.NamespacedName
81+
CABundleName types.NamespacedName
82+
OpenStackClientName types.NamespacedName
83+
OVNNorthdName types.NamespacedName
84+
OVNNorthdCertName types.NamespacedName
85+
OVNControllerName types.NamespacedName
86+
OVNControllerCertName types.NamespacedName
87+
OVNDbServerNBName types.NamespacedName
88+
OVNDbServerSBName types.NamespacedName
89+
NeutronOVNCertName types.NamespacedName
90+
OpenStackTopology []types.NamespacedName
8891
}
8992

9093
func CreateNames(openstackControlplaneName types.NamespacedName) Names {
@@ -200,6 +203,18 @@ func CreateNames(openstackControlplaneName types.NamespacedName) Names {
200203
Namespace: openstackControlplaneName.Namespace,
201204
Name: "cert-rabbitmq-cell1-svc",
202205
},
206+
NoVNCProxyCell1CertPublicRouteName: types.NamespacedName{
207+
Name: "cert-nova-novncproxy-cell1-public-route",
208+
Namespace: openstackControlplaneName.Namespace,
209+
},
210+
NoVNCProxyCell1CertPublicSvcName: types.NamespacedName{
211+
Name: "cert-nova-novncproxy-cell1-public-svc",
212+
Namespace: openstackControlplaneName.Namespace,
213+
},
214+
NoVNCProxyCell1CertVencryptName: types.NamespacedName{
215+
Name: "cert-nova-novncproxy-cell1-vencrypt",
216+
Namespace: openstackControlplaneName.Namespace,
217+
},
203218
OpenStackClientName: types.NamespacedName{
204219
Namespace: openstackControlplaneName.Namespace,
205220
Name: "openstackclient",

0 commit comments

Comments
 (0)