github.com/iter8-tools/iter8@v1.1.2/controllers/routemaps.go (about)

     1  package controllers
     2  
     3  import (
     4  	"reflect"
     5  
     6  	"github.com/iter8-tools/iter8/base/log"
     7  	corev1 "k8s.io/api/core/v1"
     8  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
     9  )
    10  
    11  // AllRoutemaps contains all the routemaps known to the controller
    12  var AllRoutemaps = routemaps{
    13  	nsRoutemap: make(map[string]routemapsByName),
    14  }
    15  
    16  // getRoutemapFromObj extracts a routemap which contains the given object as a version resource
    17  // ToDo: this function assumes that there is at most one routemap that contains a source;
    18  // a more general idea would be to return a routemap list instead
    19  func (s *routemaps) getRoutemapFromObj(obj interface{}, gvrShort string) *routemap {
    20  	// lock for reading and later unlock
    21  	s.mutex.RLock()
    22  	defer s.mutex.RUnlock()
    23  
    24  	// get unstructured object
    25  	u := obj.(*unstructured.Unstructured)
    26  
    27  	// attempt to return the routemap
    28  	// ToDo: speed up this quadruple-nested for loop
    29  	for _, rmByName := range s.nsRoutemap {
    30  		for _, rm := range rmByName {
    31  			for _, v := range rm.Versions {
    32  				for _, r := range v.Resources {
    33  					// go through every resource in every version in every routemap in every namespace
    34  					// check for name match between routemap-resource and unstructured-resource
    35  					// check for gvrShort match between routemap-resource and unstructured-resource
    36  					if r.GVRShort == gvrShort && r.Name == u.GetName() {
    37  						// if routemap specifies the resource namespace
    38  						// check for namespace match between routemap-resource and unstructured-resource
    39  						if r.Namespace == nil || *r.Namespace == u.GetNamespace() {
    40  							return rm
    41  						}
    42  					}
    43  				}
    44  			}
    45  		}
    46  	}
    47  	return nil
    48  }
    49  
    50  // GetRoutemapFromNamespaceName extracts a routemap which contains the given object as a version resource
    51  func (s *routemaps) GetRoutemapFromNamespaceName(namespace string, name string) RoutemapInterface {
    52  	// lock for reading and later unlock
    53  	s.mutex.RLock()
    54  	defer s.mutex.RUnlock()
    55  
    56  	rmByName, ok := s.nsRoutemap[namespace]
    57  	if ok {
    58  		s := rmByName[name]
    59  		if s == nil || reflect.ValueOf(s).IsNil() {
    60  			// try concatenating "-routemap" to name
    61  			s = rmByName[name+"-routemap"]
    62  			if s == nil || reflect.ValueOf(s).IsNil() {
    63  				return nil
    64  			}
    65  		}
    66  		return s
    67  	}
    68  
    69  	return nil
    70  }
    71  
    72  // delete a routemap from routemaps
    73  func (s *routemaps) delete(cm *corev1.ConfigMap) {
    74  	// lock for writing and later unlock
    75  	s.mutex.Lock()
    76  	defer s.mutex.Unlock()
    77  
    78  	// delete from nsRoutemap first
    79  	if m, ok1 := s.nsRoutemap[cm.Namespace]; ok1 {
    80  		_, ok2 := m[cm.Name]
    81  		if ok2 {
    82  			delete(m, cm.Name)
    83  			if len(m) == 0 {
    84  				log.Logger.Debug("no routemaps in namespace ", cm.Namespace)
    85  				delete(s.nsRoutemap, cm.Namespace)
    86  				log.Logger.Debug("deleted namespace ", cm.Namespace, " from routemaps")
    87  			}
    88  		}
    89  	}
    90  }
    91  
    92  // makeAndUpdateWith makes a routemap from a configmap and updates routemaps with it
    93  func (s *routemaps) makeAndUpdateWith(cm *corev1.ConfigMap, config *Config) *routemap {
    94  	// lock for writing and later unlock
    95  	s.mutex.Lock()
    96  	defer s.mutex.Unlock()
    97  
    98  	// validate the configmap
    99  	if err := validateRoutemapCM(cm); err != nil {
   100  		return nil
   101  	}
   102  
   103  	log.Logger.Trace("routemap cm is valid")
   104  
   105  	// make/update routemap with uninitialized status
   106  	var rm *routemap
   107  	var err error
   108  	if rm, err = extractRoutemap(cm, config); err != nil {
   109  		return nil
   110  	}
   111  
   112  	// insert into nsRoutemap
   113  	if _, ok := s.nsRoutemap[cm.Namespace]; !ok {
   114  		s.nsRoutemap[cm.Namespace] = make(routemapsByName)
   115  	}
   116  	s.nsRoutemap[cm.Namespace][cm.Name] = rm
   117  
   118  	return rm
   119  }