...

Source file src/github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/jvmchaos/impl.go

Documentation: github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/jvmchaos

     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 jvmchaos
    15  
    16  import (
    17  	"context"
    18  	"fmt"
    19  
    20  	"github.com/go-logr/logr"
    21  	"go.uber.org/fx"
    22  	v1 "k8s.io/api/core/v1"
    23  	"sigs.k8s.io/controller-runtime/pkg/client"
    24  
    25  	"github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
    26  	"github.com/chaos-mesh/chaos-mesh/controllers/common"
    27  	"github.com/chaos-mesh/chaos-mesh/controllers/utils/controller"
    28  	"github.com/chaos-mesh/chaos-mesh/pkg/jvm"
    29  )
    30  
    31  const sandboxPort = 10086
    32  
    33  type Impl struct {
    34  	client.Client
    35  	Log logr.Logger
    36  }
    37  
    38  // Apply applies jvm-chaos
    39  func (impl *Impl) Apply(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
    40  	jvmchaos := obj.(*v1alpha1.JVMChaos)
    41  
    42  	var pod v1.Pod
    43  	err := impl.Client.Get(ctx, controller.ParseNamespacedName(records[index].Id), &pod)
    44  	if err != nil {
    45  		// TODO: handle this error
    46  		return v1alpha1.NotInjected, err
    47  	}
    48  
    49  	impl.Log.Info("Try to apply jvm chaos", "namespace",
    50  		pod.Namespace, "name", pod.Name)
    51  
    52  	// TODO: Custom port may be required
    53  	err = jvm.ActiveSandbox(pod.Status.PodIP, sandboxPort)
    54  	if err != nil {
    55  		return v1alpha1.NotInjected, err
    56  	}
    57  
    58  	impl.Log.Info("active sandbox", "pod", pod.Name)
    59  
    60  	suid := genSUID(&pod, jvmchaos)
    61  	jsonBytes, err := jvm.ToSandboxAction(suid, jvmchaos)
    62  
    63  	if err != nil {
    64  		return v1alpha1.NotInjected, err
    65  	}
    66  	// TODO: Custom port may be required
    67  	err = jvm.InjectChaos(pod.Status.PodIP, sandboxPort, jsonBytes)
    68  	if err != nil {
    69  		return v1alpha1.NotInjected, err
    70  	}
    71  	impl.Log.Info("Inject JVM Chaos", "pod", pod.Name, "action", jvmchaos.Spec.Action)
    72  
    73  	return v1alpha1.Injected, nil
    74  }
    75  
    76  func genSUID(pod *v1.Pod, chaos *v1alpha1.JVMChaos) string {
    77  	return fmt.Sprintf("%s:%s:%s:%s:%s",
    78  		pod.Name,
    79  		chaos.Spec.Action,
    80  		chaos.Spec.Target,
    81  		chaos.Name,
    82  		chaos.Namespace)
    83  }
    84  
    85  // Recover means the reconciler recovers the chaos action
    86  func (impl *Impl) Recover(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
    87  	jvmchaos := obj.(*v1alpha1.JVMChaos)
    88  
    89  	var pod v1.Pod
    90  	err := impl.Client.Get(ctx, controller.ParseNamespacedName(records[index].Id), &pod)
    91  	if err != nil {
    92  		if client.IgnoreNotFound(err) != nil {
    93  			return v1alpha1.Injected, err
    94  		}
    95  
    96  		impl.Log.Info("Target pod has been deleted", "namespace", pod.Namespace, "name", pod.Name)
    97  		return v1alpha1.NotInjected, nil
    98  
    99  	}
   100  
   101  	impl.Log.Info("Try to recover pod", "namespace", pod.Namespace, "name", pod.Name)
   102  
   103  	suid := genSUID(&pod, jvmchaos)
   104  	jsonBytes, err := jvm.ToSandboxAction(suid, jvmchaos)
   105  	if err != nil {
   106  		return v1alpha1.Injected, err
   107  	}
   108  
   109  	// TODO: Custom port may be required
   110  	err = jvm.RecoverChaos(pod.Status.PodIP, sandboxPort, jsonBytes)
   111  
   112  	if err != nil {
   113  		return v1alpha1.Injected, err
   114  	}
   115  
   116  	return v1alpha1.NotInjected, nil
   117  }
   118  
   119  // Object would return the instance of chaos
   120  
   121  func NewImpl(c client.Client, log logr.Logger) *common.ChaosImplPair {
   122  	return &common.ChaosImplPair{
   123  		Name:   "jvmchaos",
   124  		Object: &v1alpha1.JVMChaos{},
   125  		Impl: &Impl{
   126  			Client: c,
   127  			Log:    log.WithName("jvmchaos"),
   128  		},
   129  	}
   130  }
   131  
   132  var Module = fx.Provide(
   133  	fx.Annotated{
   134  		Group:  "impl",
   135  		Target: NewImpl,
   136  	},
   137  )
   138