containerized-data-importer/pkg/operator/controller/route.go
Michael Henriksen 412b6e10ca CDI upgrade support (#929)
* * Initial upgrade support
* - Detect from reconcile loop that it is uograde flow
* - Set ObeservedVersion to target when upgrade is finished
* - Delete unused objects at the end of upgrade

* *     opertor controller unit test - detect upgrade
    *  cdi upgrade unit tests
    *  - verify upgrade flow is detected when version is updated
    *  - verify on upgrade objects are updated
    *  - verify on upgrade unused objects are deleted

* * optimize cleanuoUnusedResourses function
* fix logging error

* * CR fixes
* remove unused methods in unit tests
* use reflect.DeepEqual to compare runtime.Objects in unit test
* check DeletionTimeStamp before entering upgrade

* * uit tests - CR is deleted during/before upgrade

* * CR fixes:
* - invoke Deletion callbacks before and after resource deletion on clenaupUnusedResourse function
* - when looking for object to delete - search not only by name but by namespace as well

* * delete unused resources of previous version is CDI CRF is marked for deletion during upgrade
* add unit test for this case

* * should not start upgrade if versions are identical

* * add unit tests to verify there is no upgrade on identical versions

* CR fix - return error

* don't think we have to explicitly cleanup old resources when CDI deleted during upgrade

* refactor code and properly handle deleting resources on upgrade

* reconcile loop now does three way merge to better handle upgrade
2019-08-27 08:43:49 -04:00

110 lines
2.8 KiB
Go

/*
Copyright 2018 The CDI Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package controller
import (
"context"
"fmt"
"github.com/go-logr/logr"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
routev1 "github.com/openshift/api/route/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
)
const (
uploadProxyServiceName = "cdi-uploadproxy"
uploadProxyRouteName = uploadProxyServiceName
uploadProxyCASecret = "cdi-upload-proxy-ca-key"
)
func ensureUploadProxyRouteExists(logger logr.Logger, c client.Client, scheme *runtime.Scheme, owner metav1.Object) error {
namespace := owner.GetNamespace()
if namespace == "" {
return fmt.Errorf("cluster scoped owner not supported")
}
key := client.ObjectKey{Namespace: namespace, Name: uploadProxyRouteName}
err := c.Get(context.TODO(), key, &routev1.Route{})
if err == nil {
// route already exists, so do nothing (user can mutate this)
return nil
}
if meta.IsNoMatchError(err) {
// not in openshift
logger.V(3).Info("No match error for Route, must not be in openshift")
return nil
}
if !errors.IsNotFound(err) {
return err
}
secret := &corev1.Secret{}
key = client.ObjectKey{Namespace: namespace, Name: uploadProxyCASecret}
if err = c.Get(context.TODO(), key, secret); err != nil {
return err
}
cert, exists := secret.Data["tls.crt"]
if !exists {
return fmt.Errorf("unexpected secret format, 'tls.crt' key missing")
}
route := &routev1.Route{
ObjectMeta: metav1.ObjectMeta{
Name: uploadProxyRouteName,
Namespace: namespace,
Annotations: map[string]string{
// long timeout here to make sure client conection doesn't die during qcow->raw conversion
"haproxy.router.openshift.io/timeout": "60m",
},
},
Spec: routev1.RouteSpec{
To: routev1.RouteTargetReference{
Kind: "Service",
Name: uploadProxyServiceName,
},
TLS: &routev1.TLSConfig{
Termination: routev1.TLSTerminationReencrypt,
DestinationCACertificate: string(cert),
},
},
}
if err = controllerutil.SetControllerReference(owner, route, scheme); err != nil {
return err
}
if err = c.Create(context.TODO(), route); err != nil {
return err
}
return nil
}