...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package podhttpchaosmanager
17
18 import (
19 "context"
20
21 "github.com/go-logr/logr"
22 "github.com/pkg/errors"
23 v1 "k8s.io/api/core/v1"
24 k8sError "k8s.io/apimachinery/pkg/api/errors"
25 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
26 "k8s.io/apimachinery/pkg/runtime"
27 "k8s.io/apimachinery/pkg/types"
28 "k8s.io/client-go/util/retry"
29 "sigs.k8s.io/controller-runtime/pkg/client"
30
31 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
32 )
33
34 var (
35
36 ErrPodNotFound = errors.New("pod not found")
37
38
39
40 ErrPodNotRunning = errors.New("pod not running")
41 )
42
43
44 type PodHttpManager struct {
45 Source string
46
47 Log logr.Logger
48 client.Client
49 client.Reader
50 scheme *runtime.Scheme
51
52 Key types.NamespacedName
53 T *PodHttpTransaction
54 }
55
56
57 type CommitResponse struct {
58 Key types.NamespacedName
59 Err error
60 }
61
62
63 func (m *PodHttpManager) Commit(ctx context.Context) (int64, error) {
64 m.Log.Info("running modification on pod", "key", m.Key, "modification", m.T)
65 updateError := retry.RetryOnConflict(retry.DefaultRetry, func() error {
66 chaos := &v1alpha1.PodHttpChaos{}
67
68 err := m.Client.Get(ctx, m.Key, chaos)
69 if err != nil {
70 if !k8sError.IsNotFound(err) {
71 m.Log.Error(err, "error while getting podhttpchaos")
72 return err
73 }
74
75 err := m.CreateNewPodHttpChaos(ctx)
76 if err != nil {
77 m.Log.Error(err, "error while creating new podhttpchaos")
78 return err
79 }
80
81 return nil
82 }
83
84 err = m.T.Apply(chaos)
85 if err != nil {
86 m.Log.Error(err, "error while applying transactions", "transaction", m.T)
87 return err
88 }
89
90 return m.Client.Update(ctx, chaos)
91 })
92
93 if updateError != nil {
94 return 0, updateError
95 }
96
97 chaos := &v1alpha1.PodHttpChaos{}
98 err := m.Reader.Get(ctx, m.Key, chaos)
99 if err != nil {
100 m.Log.Error(err, "error while getting the latest generation number")
101 return 0, err
102 }
103 return chaos.GetGeneration(), nil
104 }
105
106 func (m *PodHttpManager) CreateNewPodHttpChaos(ctx context.Context) error {
107 var err error
108 chaos := &v1alpha1.PodHttpChaos{}
109
110 pod := v1.Pod{}
111 err = m.Client.Get(ctx, m.Key, &pod)
112 if err != nil {
113 if !k8sError.IsNotFound(err) {
114 m.Log.Error(err, "error while finding pod")
115 return err
116 }
117
118 m.Log.Info("pod not found", "key", m.Key, "error", err.Error())
119 err = ErrPodNotFound
120 return err
121 }
122
123 if pod.Status.Phase != v1.PodRunning {
124 m.Log.Info("pod is not running", "key", m.Key)
125 err = ErrPodNotRunning
126 return err
127 }
128
129 chaos.Name = m.Key.Name
130 chaos.Namespace = m.Key.Namespace
131 chaos.OwnerReferences = []metav1.OwnerReference{
132 {
133 APIVersion: pod.APIVersion,
134 Kind: pod.Kind,
135 Name: pod.Name,
136 UID: pod.UID,
137 },
138 }
139 err = m.T.Apply(chaos)
140 if err != nil {
141 m.Log.Error(err, "error while applying transactions", "transaction", m.T)
142 return err
143 }
144
145 return m.Client.Create(ctx, chaos)
146 }
147