Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[release-4.5] Bug 1874529: Configuring custom certificate for default console route #465

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 32 additions & 4 deletions pkg/console/controllers/route/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,16 @@ func (c *RouteSyncController) removeRoute(routeName string) error {
}

func (c *RouteSyncController) SyncDefaultRoute(operatorConfig *operatorsv1.Console) (*routev1.Route, string, error) {
requiredDefaultRoute := routesub.DefaultRoute(operatorConfig)
customTLSSecret, configErr := c.GetDefaultRouteTLSSecret(operatorConfig)
if configErr != nil {
return nil, "InvalidDefaultRouteConfig", configErr
}
customTLSCert, secretValidationErr := ValidateCustomCertSecret(customTLSSecret)
if secretValidationErr != nil {
return nil, "InvalidCustomTLSSecret", secretValidationErr
}

requiredDefaultRoute := routesub.DefaultRoute(operatorConfig, customTLSCert)

defaultRoute, _, defaultRouteError := routesub.ApplyRoute(c.routeClient, c.recorder, requiredDefaultRoute)
if defaultRouteError != nil {
Expand All @@ -201,12 +210,12 @@ func (c *RouteSyncController) SyncCustomRoute(operatorConfig *operatorsv1.Consol
return nil, "", nil
}

customSecret, configErr := c.ValidateCustomRouteConfig(operatorConfig)
customTLSSecret, configErr := c.ValidateCustomRouteConfig(operatorConfig)
if configErr != nil {
return nil, "InvalidCustomRouteConfig", configErr
}

customTLSCert, secretValidationErr := ValidateCustomCertSecret(customSecret)
customTLSCert, secretValidationErr := ValidateCustomCertSecret(customTLSSecret)
if secretValidationErr != nil {
return nil, "InvalidCustomTLSSecret", secretValidationErr
}
Expand All @@ -224,6 +233,25 @@ func (c *RouteSyncController) SyncCustomRoute(operatorConfig *operatorsv1.Consol
return customRoute, "", customRouteError
}

func (c *RouteSyncController) GetDefaultRouteTLSSecret(operatorConfig *operatorsv1.Console) (*corev1.Secret, error) {
// if custom route is set, we don't need to validate the config
// since it will be used for the custom route, not the default one
if routesub.IsCustomRouteSet(operatorConfig) {
return nil, nil
}

if !routesub.IsCustomTLSSecretSet(operatorConfig) {
return nil, nil
}

secret, secretErr := c.secretClient.Secrets(api.OpenShiftConfigNamespace).Get(c.ctx, operatorConfig.Spec.Route.Secret.Name, metav1.GetOptions{})
if secretErr != nil {
return nil, fmt.Errorf("failed to GET default route TLS secret: %s", secretErr)
}
return secret, nil
}

// TODO: Decouple and rename this method. So one will validate, other will get the secret.
func (c *RouteSyncController) ValidateCustomRouteConfig(operatorConfig *operatorsv1.Console) (*corev1.Secret, error) {
// get ingress
ingress, err := c.ingressClient.Get(c.ctx, api.ConfigResourceName, metav1.GetOptions{})
Expand All @@ -242,7 +270,7 @@ func (c *RouteSyncController) ValidateCustomRouteConfig(operatorConfig *operator
// `openshift-config` namespace and referenced in the operator config.
// If the suffix matches the cluster domain, then the secret is optional.
// If the suffix doesn't matches the cluster domain, then the secret is mandatory.
if !routesub.IsCustomRouteSecretSet(operatorConfig) {
if !routesub.IsCustomTLSSecretSet(operatorConfig) {
if !strings.HasSuffix(operatorConfig.Spec.Route.Hostname, ingress.Spec.Domain) {
return nil, fmt.Errorf("secret reference for custom route TLS secret is not defined")
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/console/subresource/route/route.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ func ApplyRoute(client routeclient.RoutesGetter, recorder events.Recorder, requi
// If custom hostname for the console is set, then the default route
// should point to the redirect `console-redirect` service and the
// created custom route should be pointing to the `console` service.
func DefaultRoute(cr *operatorv1.Console) *routev1.Route {
func DefaultRoute(cr *operatorv1.Console, tlsConfig *CustomTLSCert) *routev1.Route {
route := DefaultStub()
usePort := api.ConsoleContainerPortName
tlsTermination := routev1.TLSTerminationReencrypt
Expand All @@ -78,7 +78,7 @@ func DefaultRoute(cr *operatorv1.Console) *routev1.Route {
route.Spec = routev1.RouteSpec{
To: toService(serviceName),
Port: port(usePort),
TLS: tls(nil, tlsTermination),
TLS: tls(tlsConfig, tlsTermination),
WildcardPolicy: wildcard(),
}
util.AddOwnerRef(route, util.OwnerRefFrom(cr))
Expand Down Expand Up @@ -185,7 +185,7 @@ func IsCustomRouteSet(operatorConfig *operatorv1.Console) bool {
}

// Check if reference for secret holding custom TLS certificate and key is set
func IsCustomRouteSecretSet(operatorConfig *operatorv1.Console) bool {
func IsCustomTLSSecretSet(operatorConfig *operatorv1.Console) bool {
if operatorConfig == nil {
return false
}
Expand Down
48 changes: 46 additions & 2 deletions pkg/console/subresource/route/route_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ func TestDefaultRoute(t *testing.T) {
weight int32 = 100
)
type args struct {
cr *operatorv1.Console
cr *operatorv1.Console
tlsConfig *CustomTLSCert
}
tests := []struct {
name string
Expand All @@ -43,6 +44,47 @@ func TestDefaultRoute(t *testing.T) {
Spec: operatorv1.ConsoleSpec{},
Status: operatorv1.ConsoleStatus{},
},
tlsConfig: nil,
},
want: &routev1.Route{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{
Name: api.OpenShiftConsoleName,
Namespace: api.OpenShiftConsoleNamespace,
Labels: map[string]string{"app": api.OpenShiftConsoleName},
Annotations: map[string]string{},
},
Spec: routev1.RouteSpec{
To: routev1.RouteTargetReference{
Kind: "Service",
Name: api.OpenShiftConsoleName,
Weight: &weight,
},
Port: &routev1.RoutePort{
TargetPort: intstr.FromString(api.ConsoleContainerPortName),
},
TLS: &routev1.TLSConfig{
Termination: routev1.TLSTerminationReencrypt,
InsecureEdgeTerminationPolicy: routev1.InsecureEdgeTerminationPolicyRedirect,
},
WildcardPolicy: routev1.WildcardPolicyNone,
},
Status: routev1.RouteStatus{},
},
},
{
name: "Test default route with custom TLS",
args: args{
cr: &operatorv1.Console{
TypeMeta: metav1.TypeMeta{},
ObjectMeta: metav1.ObjectMeta{},
Spec: operatorv1.ConsoleSpec{},
Status: operatorv1.ConsoleStatus{},
},
tlsConfig: &CustomTLSCert{
Key: tlsKey,
Certificate: tlsCertificate,
},
},
want: &routev1.Route{
TypeMeta: metav1.TypeMeta{},
Expand All @@ -64,6 +106,8 @@ func TestDefaultRoute(t *testing.T) {
TLS: &routev1.TLSConfig{
Termination: routev1.TLSTerminationReencrypt,
InsecureEdgeTerminationPolicy: routev1.InsecureEdgeTerminationPolicyRedirect,
Key: tlsKey,
Certificate: tlsCertificate,
},
WildcardPolicy: routev1.WildcardPolicyNone,
},
Expand Down Expand Up @@ -113,7 +157,7 @@ func TestDefaultRoute(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if diff := deep.Equal(DefaultRoute(tt.args.cr), tt.want); diff != nil {
if diff := deep.Equal(DefaultRoute(tt.args.cr, tt.args.tlsConfig), tt.want); diff != nil {
t.Error(diff)
}
})
Expand Down