...

Source file src/github.com/chaos-mesh/chaos-mesh/pkg/router/route_table.go

Documentation: github.com/chaos-mesh/chaos-mesh/pkg/router

     1  // Copyright 2020 Chaos Mesh Authors.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // See the License for the specific language governing permissions and
    12  // limitations under the License.
    13  
    14  package router
    15  
    16  import (
    17  	"reflect"
    18  
    19  	"github.com/go-logr/logr"
    20  	"github.com/pkg/errors"
    21  	"k8s.io/apimachinery/pkg/runtime"
    22  	ctrl "sigs.k8s.io/controller-runtime"
    23  	"sigs.k8s.io/controller-runtime/pkg/client"
    24  
    25  	"github.com/chaos-mesh/chaos-mesh/pkg/config"
    26  	"github.com/chaos-mesh/chaos-mesh/pkg/router/endpoint"
    27  )
    28  
    29  type routeEntry struct {
    30  	Name      string
    31  	Object    runtime.Object
    32  	Endpoints []routeEndpoint
    33  }
    34  
    35  func newEntry(name string, obj runtime.Object) *routeEntry {
    36  	return &routeEntry{
    37  		Name:      name,
    38  		Object:    obj,
    39  		Endpoints: []routeEndpoint{},
    40  	}
    41  }
    42  
    43  type routeEndpoint struct {
    44  	RouteFunc   func(runtime.Object) bool
    45  	NewEndpoint endpoint.NewEndpoint
    46  }
    47  
    48  var routeTable map[reflect.Type]*routeEntry
    49  
    50  var log logr.Logger
    51  
    52  // Register registers an endpoint
    53  func Register(name string, obj runtime.Object, routeFunc func(runtime.Object) bool, newEndpoint endpoint.NewEndpoint) {
    54  	typ := reflect.TypeOf(obj)
    55  	_, ok := routeTable[typ]
    56  	if !ok {
    57  		routeTable[typ] = newEntry(name, obj)
    58  	}
    59  
    60  	entry := routeTable[typ]
    61  	if entry.Name != name {
    62  		err := errors.Errorf("different names for one type of resource")
    63  		log.Error(err, "different names for one type of resource", "name", name, "existingName", entry.Name)
    64  	}
    65  
    66  	entry.Endpoints = append(entry.Endpoints, routeEndpoint{
    67  		RouteFunc:   routeFunc,
    68  		NewEndpoint: newEndpoint,
    69  	})
    70  }
    71  
    72  // SetupWithManagerAndConfigs setups reconciler with manager and controller configs
    73  func SetupWithManagerAndConfigs(c client.Client, mgr ctrl.Manager, cfg *config.ChaosControllerConfig) error {
    74  	for typ, end := range routeTable {
    75  		log.Info("setup reconciler with manager", "type", typ, "endpoint", end.Name)
    76  		reconciler := NewReconciler(end.Name, end.Object, c, mgr, end.Endpoints, cfg.ClusterScoped, cfg.TargetNamespace)
    77  		err := reconciler.SetupWithManager(mgr)
    78  		if err != nil {
    79  			log.Error(err, "fail to setup reconciler with manager")
    80  
    81  			return err
    82  		}
    83  
    84  		if err := ctrl.NewWebhookManagedBy(mgr).
    85  			For(end.Object).
    86  			Complete(); err != nil {
    87  			log.Error(err, "fail to setup webhook")
    88  			return err
    89  		}
    90  	}
    91  
    92  	return nil
    93  }
    94  
    95  func init() {
    96  	routeTable = make(map[reflect.Type]*routeEntry)
    97  	log = ctrl.Log.WithName("router")
    98  }
    99