...

Source file src/github.com/chaos-mesh/chaos-mesh/controllers/utils/chaosdaemon/chaosdaemon.go

Documentation: github.com/chaos-mesh/chaos-mesh/controllers/utils/chaosdaemon

     1  // Copyright 2021 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  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  //
    15  
    16  package chaosdaemon
    17  
    18  import (
    19  	"context"
    20  
    21  	"github.com/pkg/errors"
    22  	"go.uber.org/fx"
    23  	v1 "k8s.io/api/core/v1"
    24  	"k8s.io/apimachinery/pkg/types"
    25  	ctrl "sigs.k8s.io/controller-runtime"
    26  	"sigs.k8s.io/controller-runtime/pkg/client"
    27  
    28  	"github.com/chaos-mesh/chaos-mesh/controllers/config"
    29  	chaosdaemonclient "github.com/chaos-mesh/chaos-mesh/pkg/chaosdaemon/client"
    30  	grpcUtils "github.com/chaos-mesh/chaos-mesh/pkg/grpc"
    31  	"github.com/chaos-mesh/chaos-mesh/pkg/mock"
    32  )
    33  
    34  var log = ctrl.Log.WithName("controller-chaos-daemon-client-utils")
    35  
    36  func findIPOnEndpoints(e *v1.Endpoints, nodeName string) string {
    37  	for _, subset := range e.Subsets {
    38  		for _, addr := range subset.Addresses {
    39  			if addr.NodeName != nil && *addr.NodeName == nodeName {
    40  				return addr.IP
    41  			}
    42  		}
    43  	}
    44  
    45  	return ""
    46  }
    47  
    48  type ChaosDaemonClientBuilder struct {
    49  	client.Reader
    50  }
    51  
    52  func (b *ChaosDaemonClientBuilder) FindDaemonIP(ctx context.Context, pod *v1.Pod) (string, error) {
    53  	nodeName := pod.Spec.NodeName
    54  	log.Info("Creating client to chaos-daemon", "node", nodeName)
    55  
    56  	ns := config.ControllerCfg.Namespace
    57  	var endpoints v1.Endpoints
    58  	err := b.Reader.Get(ctx, types.NamespacedName{
    59  		Namespace: ns,
    60  		Name:      "chaos-daemon",
    61  	}, &endpoints)
    62  	if err != nil {
    63  		return "", err
    64  	}
    65  
    66  	daemonIP := findIPOnEndpoints(&endpoints, nodeName)
    67  	if len(daemonIP) == 0 {
    68  		return "", errors.Errorf("cannot find daemonIP on node %s in related Endpoints %v", nodeName, endpoints)
    69  	}
    70  
    71  	return daemonIP, nil
    72  }
    73  
    74  // Build will construct a ChaosDaemonClient
    75  // The `id` parameter is the namespacedName of current handling resource,
    76  // which will be printed in the log of the chaos-daemon
    77  func (b *ChaosDaemonClientBuilder) Build(ctx context.Context, pod *v1.Pod, id *types.NamespacedName) (chaosdaemonclient.ChaosDaemonClientInterface, error) {
    78  	if cli := mock.On("MockChaosDaemonClient"); cli != nil {
    79  		return cli.(chaosdaemonclient.ChaosDaemonClientInterface), nil
    80  	}
    81  	if err := mock.On("NewChaosDaemonClientError"); err != nil {
    82  		return nil, err.(error)
    83  	}
    84  
    85  	daemonIP, err := b.FindDaemonIP(ctx, pod)
    86  	if err != nil {
    87  		return nil, err
    88  	}
    89  	builder := grpcUtils.Builder(daemonIP, config.ControllerCfg.ChaosDaemonPort).WithDefaultTimeout()
    90  	if config.ControllerCfg.TLSConfig.ChaosMeshCACert != "" {
    91  		builder.TLSFromFile(config.ControllerCfg.TLSConfig.ChaosMeshCACert, config.ControllerCfg.TLSConfig.ChaosDaemonClientCert, config.ControllerCfg.TLSConfig.ChaosDaemonClientKey)
    92  	} else {
    93  		builder.Insecure()
    94  	}
    95  
    96  	if id != nil {
    97  		builder = builder.WithNamespacedName(*id)
    98  	}
    99  
   100  	cc, err := builder.Build()
   101  	if err != nil {
   102  		return nil, err
   103  	}
   104  	return chaosdaemonclient.New(cc), nil
   105  }
   106  
   107  type ChaosDaemonClientBuilderParams struct {
   108  	fx.In
   109  
   110  	NoCacheReader           client.Reader `name:"no-cache"`
   111  	ControlPlaneCacheReader client.Reader `name:"control-plane-cache" optional:"true"`
   112  }
   113  
   114  func New(params ChaosDaemonClientBuilderParams) *ChaosDaemonClientBuilder {
   115  	var reader client.Reader
   116  	if params.ControlPlaneCacheReader != nil {
   117  		reader = params.ControlPlaneCacheReader
   118  	} else {
   119  		reader = params.NoCacheReader
   120  	}
   121  	return &ChaosDaemonClientBuilder{
   122  		Reader: reader,
   123  	}
   124  }
   125