1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package ec2stop
17
18 import (
19 "context"
20 "encoding/json"
21
22 "github.com/aws/aws-sdk-go-v2/aws"
23 awscfg "github.com/aws/aws-sdk-go-v2/config"
24 "github.com/aws/aws-sdk-go-v2/credentials"
25 "github.com/aws/aws-sdk-go-v2/service/ec2"
26 "github.com/go-logr/logr"
27 v1 "k8s.io/api/core/v1"
28 "k8s.io/apimachinery/pkg/types"
29 "sigs.k8s.io/controller-runtime/pkg/client"
30
31 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
32 impltypes "github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/types"
33 )
34
35 var _ impltypes.ChaosImpl = (*Impl)(nil)
36
37 type Impl struct {
38 client.Client
39
40 Log logr.Logger
41 }
42
43 func (impl *Impl) Apply(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
44 awschaos := obj.(*v1alpha1.AWSChaos)
45
46 var selected v1alpha1.AWSSelector
47 json.Unmarshal([]byte(records[index].Id), &selected)
48
49 opts := []func(*awscfg.LoadOptions) error{
50 awscfg.WithRegion(selected.AWSRegion),
51 }
52
53 if selected.Endpoint != nil {
54 opts = append(opts, awscfg.WithEndpointResolver(aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) {
55 return aws.Endpoint{URL: *selected.Endpoint, SigningRegion: region}, nil
56 })))
57 }
58
59 if awschaos.Spec.SecretName != nil {
60 secret := &v1.Secret{}
61 err := impl.Client.Get(ctx, types.NamespacedName{
62 Name: *awschaos.Spec.SecretName,
63 Namespace: awschaos.Namespace,
64 }, secret)
65 if err != nil {
66 impl.Log.Error(err, "fail to get cloud secret")
67 return v1alpha1.NotInjected, err
68 }
69 opts = append(opts, awscfg.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(
70 string(secret.Data["aws_access_key_id"]),
71 string(secret.Data["aws_secret_access_key"]),
72 "",
73 )))
74 }
75 cfg, err := awscfg.LoadDefaultConfig(ctx, opts...)
76 if err != nil {
77 impl.Log.Error(err, "unable to load aws SDK config")
78 return v1alpha1.NotInjected, err
79 }
80 ec2client := ec2.NewFromConfig(cfg)
81
82 _, err = ec2client.StopInstances(context.TODO(), &ec2.StopInstancesInput{
83 InstanceIds: []string{selected.Ec2Instance},
84 })
85
86 if err != nil {
87 return v1alpha1.NotInjected, err
88 }
89
90 return v1alpha1.Injected, nil
91 }
92
93 func (impl *Impl) Recover(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
94 awschaos := obj.(*v1alpha1.AWSChaos)
95
96 var selected v1alpha1.AWSSelector
97 json.Unmarshal([]byte(records[index].Id), &selected)
98
99 opts := []func(*awscfg.LoadOptions) error{
100 awscfg.WithRegion(selected.AWSRegion),
101 }
102
103 if selected.Endpoint != nil {
104 opts = append(opts, awscfg.WithEndpointResolver(aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) {
105 return aws.Endpoint{URL: *selected.Endpoint, SigningRegion: region}, nil
106 })))
107 }
108 if awschaos.Spec.SecretName != nil {
109 secret := &v1.Secret{}
110 err := impl.Client.Get(ctx, types.NamespacedName{
111 Name: *awschaos.Spec.SecretName,
112 Namespace: awschaos.Namespace,
113 }, secret)
114 if err != nil {
115 impl.Log.Error(err, "fail to get cloud secret")
116 return v1alpha1.Injected, err
117 }
118 opts = append(opts, awscfg.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(
119 string(secret.Data["aws_access_key_id"]),
120 string(secret.Data["aws_secret_access_key"]),
121 "",
122 )))
123 }
124 cfg, err := awscfg.LoadDefaultConfig(ctx, opts...)
125 if err != nil {
126 impl.Log.Error(err, "unable to load aws SDK config")
127 return v1alpha1.Injected, err
128 }
129 ec2client := ec2.NewFromConfig(cfg)
130
131 _, err = ec2client.StartInstances(context.TODO(), &ec2.StartInstancesInput{
132 InstanceIds: []string{selected.Ec2Instance},
133 })
134
135 if err != nil {
136 impl.Log.Error(err, "fail to start the instance")
137 return v1alpha1.Injected, err
138 }
139
140 return v1alpha1.NotInjected, nil
141 }
142
143 func NewImpl(c client.Client, log logr.Logger) *Impl {
144 return &Impl{
145 Client: c,
146 Log: log.WithName("ec2stop"),
147 }
148 }
149