...

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

Documentation: github.com/chaos-mesh/chaos-mesh/controllers/chaosimpl/awschaos/ec2stop

     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 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  	err := json.Unmarshal([]byte(records[index].Id), &selected)
    48  	if err != nil {
    49  		impl.Log.Error(err, "fail to unmarshal the selector")
    50  		return v1alpha1.NotInjected, err
    51  	}
    52  
    53  	opts := []func(*awscfg.LoadOptions) error{
    54  		awscfg.WithRegion(selected.AWSRegion),
    55  	}
    56  
    57  	if selected.Endpoint != nil {
    58  		opts = append(opts, awscfg.WithEndpointResolver(aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) {
    59  			return aws.Endpoint{URL: *selected.Endpoint, SigningRegion: region}, nil
    60  		})))
    61  	}
    62  
    63  	if awschaos.Spec.SecretName != nil {
    64  		secret := &v1.Secret{}
    65  		err := impl.Client.Get(ctx, types.NamespacedName{
    66  			Name:      *awschaos.Spec.SecretName,
    67  			Namespace: awschaos.Namespace,
    68  		}, secret)
    69  		if err != nil {
    70  			impl.Log.Error(err, "fail to get cloud secret")
    71  			return v1alpha1.NotInjected, err
    72  		}
    73  		opts = append(opts, awscfg.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(
    74  			string(secret.Data["aws_access_key_id"]),
    75  			string(secret.Data["aws_secret_access_key"]),
    76  			string(secret.Data["aws_session_token"]),
    77  		)))
    78  	}
    79  	cfg, err := awscfg.LoadDefaultConfig(ctx, opts...)
    80  	if err != nil {
    81  		impl.Log.Error(err, "unable to load aws SDK config")
    82  		return v1alpha1.NotInjected, err
    83  	}
    84  	ec2client := ec2.NewFromConfig(cfg)
    85  
    86  	_, err = ec2client.StopInstances(context.TODO(), &ec2.StopInstancesInput{
    87  		InstanceIds: []string{selected.Ec2Instance},
    88  	})
    89  
    90  	if err != nil {
    91  		return v1alpha1.NotInjected, err
    92  	}
    93  
    94  	return v1alpha1.Injected, nil
    95  }
    96  
    97  func (impl *Impl) Recover(ctx context.Context, index int, records []*v1alpha1.Record, obj v1alpha1.InnerObject) (v1alpha1.Phase, error) {
    98  	awschaos := obj.(*v1alpha1.AWSChaos)
    99  
   100  	var selected v1alpha1.AWSSelector
   101  	err := json.Unmarshal([]byte(records[index].Id), &selected)
   102  	if err != nil {
   103  		impl.Log.Error(err, "fail to unmarshal the selector")
   104  		return v1alpha1.NotInjected, err
   105  	}
   106  
   107  	opts := []func(*awscfg.LoadOptions) error{
   108  		awscfg.WithRegion(selected.AWSRegion),
   109  	}
   110  
   111  	if selected.Endpoint != nil {
   112  		opts = append(opts, awscfg.WithEndpointResolver(aws.EndpointResolverFunc(func(service, region string) (aws.Endpoint, error) {
   113  			return aws.Endpoint{URL: *selected.Endpoint, SigningRegion: region}, nil
   114  		})))
   115  	}
   116  	if awschaos.Spec.SecretName != nil {
   117  		secret := &v1.Secret{}
   118  		err := impl.Client.Get(ctx, types.NamespacedName{
   119  			Name:      *awschaos.Spec.SecretName,
   120  			Namespace: awschaos.Namespace,
   121  		}, secret)
   122  		if err != nil {
   123  			impl.Log.Error(err, "fail to get cloud secret")
   124  			return v1alpha1.Injected, err
   125  		}
   126  		opts = append(opts, awscfg.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(
   127  			string(secret.Data["aws_access_key_id"]),
   128  			string(secret.Data["aws_secret_access_key"]),
   129  			string(secret.Data["aws_session_token"]),
   130  		)))
   131  	}
   132  	cfg, err := awscfg.LoadDefaultConfig(ctx, opts...)
   133  	if err != nil {
   134  		impl.Log.Error(err, "unable to load aws SDK config")
   135  		return v1alpha1.Injected, err
   136  	}
   137  	ec2client := ec2.NewFromConfig(cfg)
   138  
   139  	_, err = ec2client.StartInstances(context.TODO(), &ec2.StartInstancesInput{
   140  		InstanceIds: []string{selected.Ec2Instance},
   141  	})
   142  
   143  	if err != nil {
   144  		impl.Log.Error(err, "fail to start the instance")
   145  		return v1alpha1.Injected, err
   146  	}
   147  
   148  	return v1alpha1.NotInjected, nil
   149  }
   150  
   151  func NewImpl(c client.Client, log logr.Logger) *Impl {
   152  	return &Impl{
   153  		Client: c,
   154  		Log:    log.WithName("ec2stop"),
   155  	}
   156  }
   157