Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 70 additions & 0 deletions controllers/autodetect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You 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.
*/

// Copied from grafana-operator
// With the Apache License: https://github.com/grafana/grafana-operator/blob/master/LICENSE
// See: https://github.com/grafana/grafana-operator/blob/master/controllers/autodetect/main.go
// Package autodetect is for auto-detecting traits from the environment (platform, APIs, ...).
package controllers

import (
"k8s.io/client-go/discovery"
"k8s.io/client-go/rest"
)

var _ AutoDetect = (*autoDetect)(nil)

// AutoDetect provides an assortment of routines that auto-detect traits based on the runtime.
type AutoDetect interface {
IsOpenshift() (bool, error)
}

type autoDetect struct {
dcl discovery.DiscoveryInterface
}

// New creates a new auto-detection worker, using the given client when talking to the current cluster.
func NewAutodetect(restConfig *rest.Config) (AutoDetect, error) {
dcl, err := discovery.NewDiscoveryClientForConfig(restConfig)
if err != nil {
// it's pretty much impossible to get into this problem, as most of the
// code branches from the previous call just won't fail at all,
// but let's handle this error anyway...
return nil, err
}

return &autoDetect{
dcl: dcl,
}, nil
}

// Platform returns the detected platform this operator is running on. Possible values: Kubernetes, OpenShift.
func (a *autoDetect) IsOpenshift() (bool, error) {
apiList, err := a.dcl.ServerGroups()
if err != nil {
return false, err
}

apiGroups := apiList.Groups
for i := range apiGroups {
if apiGroups[i].Name == "route.openshift.io" {
return true, nil
}
}

return false, nil
}
5 changes: 3 additions & 2 deletions controllers/solrcloud_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ import (
// SolrCloudReconciler reconciles a SolrCloud object
type SolrCloudReconciler struct {
client.Client
Scheme *runtime.Scheme
Scheme *runtime.Scheme
IsOpenShift bool
}

var useZkCRD bool
Expand Down Expand Up @@ -328,7 +329,7 @@ func (r *SolrCloudReconciler) Reconcile(ctx context.Context, req ctrl.Request) (
var statefulSet *appsv1.StatefulSet
if !blockReconciliationOfStatefulSet {
// Generate StatefulSet that should exist
expectedStatefulSet := util.GenerateStatefulSet(instance, &newStatus, hostNameIpMap, reconcileConfigInfo, tls, security)
expectedStatefulSet := util.GenerateStatefulSet(instance, &newStatus, hostNameIpMap, reconcileConfigInfo, tls, security, r.IsOpenShift)

// Check if the StatefulSet already exists
statefulSetLogger := logger.WithValues("statefulSet", expectedStatefulSet.Name)
Expand Down
5 changes: 3 additions & 2 deletions controllers/suite_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -106,8 +106,9 @@ var _ = BeforeSuite(func(ctx context.Context) {
// Start up Reconcilers
By("starting the reconcilers")
Expect((&SolrCloudReconciler{
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
Client: k8sManager.GetClient(),
Scheme: k8sManager.GetScheme(),
IsOpenShift: false,
}).SetupWithManager(k8sManager)).To(Succeed())

Expect((&SolrPrometheusExporterReconciler{
Expand Down
21 changes: 11 additions & 10 deletions controllers/util/solr_util.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ var (
// replicas: the number of replicas for the SolrCloud instance
// storage: the size of the storage for the SolrCloud instance (e.g. 100Gi)
// zkConnectionString: the connectionString of the ZK instance to connect to
func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus *solr.SolrCloudStatus, hostNameIPs map[string]string, reconcileConfigInfo map[string]string, tls *TLSCerts, security *SecurityConfig) *appsv1.StatefulSet {
func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus *solr.SolrCloudStatus, hostNameIPs map[string]string, reconcileConfigInfo map[string]string, tls *TLSCerts, security *SecurityConfig, isOpenShift bool) *appsv1.StatefulSet {
terminationGracePeriod := int64(60)
shareProcessNamespace := false
solrPodPort := solrCloud.Spec.SolrAddressability.PodPort
Expand Down Expand Up @@ -549,19 +549,20 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus *solr.SolrCl
Spec: corev1.PodSpec{
TerminationGracePeriodSeconds: &terminationGracePeriod,
ShareProcessNamespace: &shareProcessNamespace,
SecurityContext: &corev1.PodSecurityContext{
FSGroup: &defaultFSGroup,
},
Volumes: solrVolumes,
InitContainers: initContainers,
HostAliases: hostAliases,
Containers: containers,
ReadinessGates: podReadinessGates,
SecurityContext: &corev1.PodSecurityContext{},
Volumes: solrVolumes,
InitContainers: initContainers,
HostAliases: hostAliases,
Containers: containers,
ReadinessGates: podReadinessGates,
},
},
VolumeClaimTemplates: pvcs,
},
}
if !isOpenShift {
stateful.Spec.Template.Spec.SecurityContext.FSGroup = &defaultFSGroup
}
if solrCloud.UsesHeadlessService() {
stateful.Spec.Template.Spec.Subdomain = solrCloud.HeadlessServiceName()
}
Expand Down Expand Up @@ -598,7 +599,7 @@ func GenerateStatefulSet(solrCloud *solr.SolrCloud, solrCloudStatus *solr.SolrCl

if customPodOptions.PodSecurityContext != nil {
stateful.Spec.Template.Spec.SecurityContext = customPodOptions.PodSecurityContext
if stateful.Spec.Template.Spec.SecurityContext.FSGroup == nil {
if stateful.Spec.Template.Spec.SecurityContext.FSGroup == nil && !isOpenShift {
stateful.Spec.Template.Spec.SecurityContext.FSGroup = &defaultFSGroup
}
}
Expand Down
21 changes: 19 additions & 2 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -198,9 +198,26 @@ func main() {
}
}

// Fetch k8s api credentials and detect platform
restConfig := ctrl.GetConfigOrDie()

autodetect, err := controllers.NewAutodetect(restConfig)
if err != nil {
setupLog.Error(err, "failed to setup auto-detect routine")
os.Exit(1)
}

isOpenShift, err := autodetect.IsOpenshift()
setupLog.Info("autodetect", "isOpenShift", isOpenShift)
if err != nil {
setupLog.Error(err, "unable to detect the platform")
os.Exit(1)
}

if err = (&controllers.SolrCloudReconciler{
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
Client: mgr.GetClient(),
Scheme: mgr.GetScheme(),
IsOpenShift: isOpenShift,
}).SetupWithManager(mgr); err != nil {
setupLog.Error(err, "unable to create controller", "controller", "SolrCloud")
os.Exit(1)
Expand Down