Completed
Pull Request — master (#640)
by
unknown
03:00
created

BaseAction.elb_connect()   A

Complexity

Conditions 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
dl 0
loc 4
rs 10
c 1
b 0
f 0
1
import re
2
import eventlet
3
import importlib
4
5
import boto.ec2
6
import boto.route53
7
import boto.vpc
8
9
from st2actions.runners.pythonrunner import Action
10
from ec2parsers import ResultSets
11
12
13
class BaseAction(Action):
14
15
    def __init__(self, config):
16
        super(BaseAction, self).__init__(config)
17
18
        self.credentials = {
19
            'region': None,
20
            'aws_access_key_id': None,
21
            'aws_secret_access_key': None
22
        }
23
24
        if config['st2_user_data']:
25
            with open(config['st2_user_data'], 'r') as fp:
26
                self.userdata = fp.read()
27
        else:
28
            self.userdata = None
29
30
        # Note: In old static config credentials and region are under "setup" key and with a new
31
        # dynamic config values are top-level
32
        access_key_id = config.get('aws_access_key_id', None)
33
        secret_access_key = config.get('aws_secret_access_key', None)
34
        region = config.get('region', None)
35
36
        if access_key_id and secret_access_key:
37
            self.credentials['aws_access_key_id'] = access_key_id
38
            self.credentials['aws_secret_access_key'] = secret_access_key
39
            self.credentials['region'] = region
40
        else:
41
            # Assume old-style config
42
            self.credentials = config['setup']
43
44
        self.resultsets = ResultSets()
45
46
    def ec2_connect(self):
47
        region = self.credentials['region']
48
        del self.credentials['region']
49
        return boto.ec2.connect_to_region(region, **self.credentials)
50
51
    def vpc_connect(self):
52
        region = self.credentials['region']
53
        del self.credentials['region']
54
        return boto.vpc.connect_to_region(region, **self.credentials)
55
56
    def elb_connect(self):
57
        region = self.credentials['region']
58
        del self.credentials['region']
59
        return boto.ec2.elb.connect_to_region(region, **self.credentials)
60
61
    def r53_connect(self):
62
        del self.credentials['region']
63
        return boto.route53.connection.Route53Connection(**self.credentials)
64
65
    def get_r53zone(self, zone):
66
        conn = self.r53_connect()
67
        return conn.get_zone(zone)
68
69
    def st2_user_data(self):
70
        return self.userdata
71
72
    def split_tags(self, tags):
73
        tag_dict = {}
74
        split_tags = tags.split(',')
75
        for tag in split_tags:
76
            if re.search('=', tag):
77
                k, v = tag.split('=', 1)
78
                tag_dict[k] = v
79
        return tag_dict
80
81
    def wait_for_state(self, instance_id, state, timeout=10, retries=3):
82
        state_list = {}
83
        obj = self.ec2_connect()
84
        eventlet.sleep(timeout)
85
        instance_list = []
86
87
        for _ in range(retries + 1):
88
            try:
89
                instance_list = obj.get_only_instances([instance_id, ])
90
            except Exception:
91
                self.logger.info("Waiting for instance to become available")
92
                eventlet.sleep(timeout)
93
94
        for instance in instance_list:
95
            try:
96
                current_state = instance.update()
97
            except Exception, e:
98
                self.logger.info("Instance (%s) not listed. Error: %s" %
99
                                 (instance_id, e))
100
                eventlet.sleep(timeout)
101
102
            while current_state != state:
103
                current_state = instance.update()
104
            state_list[instance_id] = current_state
105
        return state_list
106
107
    def do_method(self, module_path, cls, action, **kwargs):
108
        module = importlib.import_module(module_path)
109
        # hack to connect to correct region
110
        if cls == 'EC2Connection':
111
            obj = self.ec2_connect()
112
        elif cls == 'VPCConnection':
113
            obj = self.vpc_connect()
114
        elif cls == 'ELBConnection':
115
            obj = self.elb_connect()
116
        elif module_path == 'boto.route53.zone' and cls == 'Zone':
117
            zone = kwargs['zone']
118
            del kwargs['zone']
119
            obj = self.get_r53zone(zone)
120
        else:
121
            del self.credentials['region']
122
            obj = getattr(module, cls)(**self.credentials)
123
124
        if not obj:
125
            raise ValueError('Invalid or missing credentials (aws_access_key_id,'
126
                             'aws_secret_access_key) or region')
127
128
        resultset = getattr(obj, action)(**kwargs)
129
        formatted = self.resultsets.formatter(resultset)
130
        return formatted if isinstance(formatted, list) else [formatted]
131
132
    def do_function(self, module_path, action, **kwargs):
133
        module = __import__(module_path)
134
        return getattr(module, action)(**kwargs)
135