Add Route pointing to the HTTP Service when the Route API is present

This commit is contained in:
Akram Ben Aissi 2020-05-04 19:02:53 +02:00
parent b66fab6cec
commit b6144b5559
7 changed files with 115 additions and 5 deletions

View File

@ -45,8 +45,6 @@ var (
operatorMetricsPort int32 = 8686
)
//var log = logf.Log.WithName("cmd")
func printInfo() {
log.Log.Info(fmt.Sprintf("Version: %s", version.Version))
log.Log.Info(fmt.Sprintf("Git commit: %s", version.GitCommit))

View File

@ -177,13 +177,19 @@ func (r *ReconcileJenkinsBaseConfiguration) ensureResourcesRequiredForJenkinsPod
}
r.logger.V(log.VDebug).Info("Extra role bindings are present")
if err := r.createService(metaObject, resources.GetJenkinsHTTPServiceName(r.Configuration.Jenkins), r.Configuration.Jenkins.Spec.Service); err != nil {
httpServiceName := resources.GetJenkinsHTTPServiceName(r.Configuration.Jenkins)
if err := r.createService(metaObject, httpServiceName, r.Configuration.Jenkins.Spec.Service); err != nil {
return err
}
r.logger.V(log.VDebug).Info("Jenkins HTTP Service is present")
if err := r.createService(metaObject, resources.GetJenkinsSlavesServiceName(r.Configuration.Jenkins), r.Configuration.Jenkins.Spec.SlaveService); err != nil {
return err
}
if resources.IsRouteAPIAvailable(r.ClientSet) {
if err := r.createRoute(metaObject, httpServiceName, r.Configuration.Jenkins); err != nil {
return err
}
}
r.logger.V(log.VDebug).Info("Jenkins slave Service is present")
return nil

View File

@ -0,0 +1,47 @@
package resources
import (
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
routev1 "github.com/openshift/api/route/v1"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apimachinery/pkg/util/intstr"
"k8s.io/client-go/discovery"
"k8s.io/client-go/kubernetes"
)
//RouteKind the kind name for route
const RouteKind = "Route"
var isRouteAPIAvailable = false
var routeAPIChecked = false
// UpdateRoute returns new route matching the service
func UpdateRoute(actual routev1.Route,jenkins *v1alpha2.Jenkins) routev1.Route {
actualTargetService := actual.Spec.To
serviceName := GetJenkinsHTTPServiceName(jenkins)
if( actualTargetService.Name != serviceName ) {
actual.Spec.To.Name = serviceName
}
port := jenkins.Spec.Service.Port
if( actual.Spec.Port.TargetPort.IntVal != port){
actual.Spec.Port.TargetPort = intstr.FromInt(int(port))
}
return actual
}
//IsRouteAPIDiscoverable tells if the Route API is installed and discoverable
func IsRouteAPIAvailable(clientSet kubernetes.Clientset) (bool) {
if (routeAPIChecked){
return isRouteAPIAvailable
}
gv := schema.GroupVersion{
Group: routev1.GroupName,
Version: routev1.SchemeGroupVersion.Version,
}
if err := discovery.ServerSupportsVersion(clientSet, gv); err != nil {
// error, API not available
return false
}
// API Exists
return true
}

View File

@ -12,6 +12,8 @@ import (
"net"
"strings"
)
//ServiceKind the kind name for Service
const ServiceKind = "Service"
// UpdateService returns new service with override fields from config
func UpdateService(actual corev1.Service, config v1alpha2.Service) corev1.Service {

View File

@ -0,0 +1,57 @@
package base
import (
"context"
"fmt"
"github.com/jenkinsci/kubernetes-operator/pkg/apis/jenkins/v1alpha2"
"k8s.io/apimachinery/pkg/util/intstr"
"github.com/jenkinsci/kubernetes-operator/pkg/controller/jenkins/configuration/base/resources"
routev1 "github.com/openshift/api/route/v1"
stackerr "github.com/pkg/errors"
apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
)
// createRoute takes the ServiceName and Creates the Route based on it
func (r *ReconcileJenkinsBaseConfiguration) createRoute(meta metav1.ObjectMeta, serviceName string, config *v1alpha2.Jenkins) error{
route := routev1.Route{}
name := fmt.Sprintf("%s-%s", config.ObjectMeta.Name, config.ObjectMeta.Namespace)
err := r.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: meta.Namespace}, &route)
if err != nil && apierrors.IsNotFound(err) {
port := &routev1.RoutePort{
TargetPort: intstr.FromString(""),
}
routeSpec := routev1.RouteSpec{
TLS: &routev1.TLSConfig{
InsecureEdgeTerminationPolicy: routev1.InsecureEdgeTerminationPolicyRedirect,
Termination: routev1.TLSTerminationEdge,
},
To: routev1.RouteTargetReference{
Kind: resources.ServiceKind,
Name: serviceName,
},
Port: port,
}
actual := routev1.Route{
ObjectMeta: metav1.ObjectMeta{
Name: name,
Namespace: meta.Namespace,
Labels: meta.Labels,
},
Spec: routeSpec,
}
route = resources.UpdateRoute(actual, config)
if err = r.CreateResource(&route); err != nil {
return stackerr.WithStack(err)
}
} else if err != nil {
return stackerr.WithStack(err)
}
route.ObjectMeta.Labels = meta.Labels // make sure that user won't break service by hand
route = resources.UpdateRoute(route, config)
return stackerr.WithStack(r.UpdateResource(&route))
}

View File

@ -72,7 +72,6 @@ func (e *enqueueRequestForJenkins) getOwnerReconcileRequests(object metav1.Objec
Name: object.GetLabels()[constants.LabelJenkinsCRKey],
}}
}
return nil
}

View File

@ -47,7 +47,8 @@ var reconcileErrors = map[string]reconcileError{}
// Add creates a new Jenkins Controller and adds it to the Manager. The Manager will set fields on the Controller
// and Start it when the Manager is Started.
func Add(mgr manager.Manager, jenkinsAPIConnectionSettings jenkinsclient.JenkinsAPIConnectionSettings, clientSet kubernetes.Clientset, config rest.Config, notificationEvents *chan event.Event) error {
return add(mgr, newReconciler(mgr, jenkinsAPIConnectionSettings, clientSet, config, notificationEvents))
reconciler := newReconciler(mgr, jenkinsAPIConnectionSettings, clientSet, config, notificationEvents)
return add(mgr, reconciler)
}
// newReconciler returns a new reconcile.Reconciler