github.com/IBM-Blockchain/fabric-operator@v1.0.4/pkg/manager/resources/route/manager.go (about)

     1  /*
     2   * Copyright contributors to the Hyperledger Fabric Operator project
     3   *
     4   * SPDX-License-Identifier: Apache-2.0
     5   *
     6   * Licensed under the Apache License, Version 2.0 (the "License");
     7   * you may not use this file except in compliance with the License.
     8   * You may obtain a copy of the License at:
     9   *
    10   * 	  http://www.apache.org/licenses/LICENSE-2.0
    11   *
    12   * Unless required by applicable law or agreed to in writing, software
    13   * distributed under the License is distributed on an "AS IS" BASIS,
    14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    15   * See the License for the specific language governing permissions and
    16   * limitations under the License.
    17   */
    18  
    19  package route
    20  
    21  import (
    22  	"context"
    23  	"fmt"
    24  
    25  	k8sclient "github.com/IBM-Blockchain/fabric-operator/pkg/k8s/controllerclient"
    26  	"github.com/IBM-Blockchain/fabric-operator/pkg/manager/resources"
    27  	"github.com/IBM-Blockchain/fabric-operator/pkg/util"
    28  	routev1 "github.com/openshift/api/route/v1"
    29  	"github.com/pkg/errors"
    30  	k8serrors "k8s.io/apimachinery/pkg/api/errors"
    31  	v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    32  	"k8s.io/apimachinery/pkg/runtime"
    33  	"k8s.io/apimachinery/pkg/types"
    34  	"sigs.k8s.io/controller-runtime/pkg/client"
    35  	logf "sigs.k8s.io/controller-runtime/pkg/log"
    36  )
    37  
    38  var log = logf.Log.WithName("route_manager")
    39  
    40  type Manager struct {
    41  	Client    k8sclient.Client
    42  	Scheme    *runtime.Scheme
    43  	RouteFile string
    44  	Name      string
    45  
    46  	LabelsFunc   func(v1.Object) map[string]string
    47  	OverrideFunc func(v1.Object, *routev1.Route, resources.Action) error
    48  }
    49  
    50  func (m *Manager) GetName(instance v1.Object) string {
    51  	if m.Name != "" {
    52  		return GetName(instance, m.Name)
    53  	}
    54  	return GetName(instance)
    55  }
    56  
    57  func (m *Manager) Reconcile(instance v1.Object, update bool) error {
    58  	name := m.GetName(instance)
    59  	route := &routev1.Route{
    60  		TypeMeta: v1.TypeMeta{
    61  			APIVersion: "route.openshift.io/v1",
    62  			Kind:       "Route",
    63  		},
    64  	}
    65  	err := m.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: instance.GetNamespace()}, route)
    66  	if err != nil {
    67  		if k8serrors.IsNotFound(err) {
    68  			log.Info(fmt.Sprintf("Creating route '%s'", name))
    69  			route, err := m.GetRouteBasedOnCRFromFile(instance)
    70  			if err != nil {
    71  				return err
    72  			}
    73  			route.TypeMeta.APIVersion = "route.openshift.io/v1"
    74  			route.TypeMeta.Kind = "Route"
    75  
    76  			err = m.Client.Create(context.TODO(), route, k8sclient.CreateOption{Owner: instance, Scheme: m.Scheme})
    77  			if err != nil {
    78  				return err
    79  			}
    80  			return nil
    81  		}
    82  		return err
    83  	}
    84  
    85  	// TODO: If needed, update logic for route goes here
    86  
    87  	return nil
    88  }
    89  
    90  func (m *Manager) GetRouteBasedOnCRFromFile(instance v1.Object) (*routev1.Route, error) {
    91  	route, err := util.GetRouteFromFile(m.RouteFile)
    92  	if err != nil {
    93  		log.Error(err, fmt.Sprintf("Error reading route configuration file: %s", m.RouteFile))
    94  		return nil, err
    95  	}
    96  
    97  	route.Name = m.GetName(instance)
    98  	route.Namespace = instance.GetNamespace()
    99  	route.Labels = m.LabelsFunc(instance)
   100  
   101  	return m.BasedOnCR(instance, route)
   102  }
   103  
   104  func (m *Manager) BasedOnCR(instance v1.Object, route *routev1.Route) (*routev1.Route, error) {
   105  	if m.OverrideFunc != nil {
   106  		err := m.OverrideFunc(instance, route, resources.Create)
   107  		if err != nil {
   108  			return nil, errors.Wrap(err, "failed during route override")
   109  		}
   110  	}
   111  
   112  	return route, nil
   113  }
   114  
   115  func (m *Manager) Get(instance v1.Object) (client.Object, error) {
   116  	if instance == nil {
   117  		return nil, nil // Instance has not been reconciled yet
   118  	}
   119  
   120  	name := m.GetName(instance)
   121  	route := &routev1.Route{}
   122  	err := m.Client.Get(context.TODO(), types.NamespacedName{Name: name, Namespace: instance.GetNamespace()}, route)
   123  	if err != nil {
   124  		return nil, err
   125  	}
   126  
   127  	return route, nil
   128  }
   129  
   130  func (m *Manager) Exists(instance v1.Object) bool {
   131  	_, err := m.Get(instance)
   132  	if err != nil {
   133  		return false
   134  	}
   135  
   136  	return true
   137  }
   138  
   139  func (m *Manager) Delete(instance v1.Object) error {
   140  	route, err := m.Get(instance)
   141  	if err != nil {
   142  		if !k8serrors.IsNotFound(err) {
   143  			return err
   144  		}
   145  	}
   146  
   147  	if route == nil {
   148  		return nil
   149  	}
   150  
   151  	err = m.Client.Delete(context.TODO(), route)
   152  	if err != nil {
   153  		if !k8serrors.IsNotFound(err) {
   154  			return err
   155  		}
   156  	}
   157  
   158  	return nil
   159  }
   160  
   161  func (m *Manager) CheckState(instance v1.Object) error {
   162  	// NO-OP
   163  	return nil
   164  }
   165  
   166  func (m *Manager) RestoreState(instance v1.Object) error {
   167  	// NO-OP
   168  	return nil
   169  }
   170  
   171  func (m *Manager) SetCustomName(name string) {
   172  	// NO-OP
   173  }
   174  
   175  func GetName(instance v1.Object, suffix ...string) string {
   176  	if len(suffix) != 0 {
   177  		if suffix[0] != "" {
   178  			return fmt.Sprintf("%s-%s", instance.GetName(), suffix[0])
   179  		}
   180  	}
   181  	return fmt.Sprintf("%s", instance.GetName())
   182  }