Completed
Push — master ( 85147e...d9066e )
by Tomaz
03:35
created

BaseAction.get_r53zone()   A

Complexity

Conditions 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
dl 0
loc 3
rs 10
c 0
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 r53_connect(self):
57
        del self.credentials['region']
58
        return boto.route53.connection.Route53Connection(**self.credentials)
59
60
    def get_r53zone(self, zone):
61
        conn = self.r53_connect()
62
        return conn.get_zone(zone)
63
64
    def st2_user_data(self):
65
        return self.userdata
66
67
    def split_tags(self, tags):
68
        tag_dict = {}
69
        split_tags = tags.split(',')
70
        for tag in split_tags:
71
            if re.search('=', tag):
72
                k, v = tag.split('=', 1)
73
                tag_dict[k] = v
74
        return tag_dict
75
76
    def wait_for_state(self, instance_id, state, timeout=10, retries=3):
77
        state_list = {}
78
        obj = self.ec2_connect()
79
        eventlet.sleep(timeout)
80
        instance_list = []
81
82
        for _ in range(retries + 1):
83
            try:
84
                instance_list = obj.get_only_instances([instance_id, ])
85
            except Exception:
86
                self.logger.info("Waiting for instance to become available")
87
                eventlet.sleep(timeout)
88
89
        for instance in instance_list:
90
            try:
91
                current_state = instance.update()
92
            except Exception, e:
93
                self.logger.info("Instance (%s) not listed. Error: %s" %
94
                                 (instance_id, e))
95
                eventlet.sleep(timeout)
96
97
            while current_state != state:
98
                current_state = instance.update()
99
            state_list[instance_id] = current_state
100
        return state_list
101
102
    def do_method(self, module_path, cls, action, **kwargs):
103
        module = importlib.import_module(module_path)
104
        # hack to connect to correct region
105
        if cls == 'EC2Connection':
106
            obj = self.ec2_connect()
107
        elif cls == 'VPCConnection':
108
            obj = self.vpc_connect()
109
        elif module_path == 'boto.route53.zone' and cls == 'Zone':
110
            zone = kwargs['zone']
111
            del kwargs['zone']
112
            obj = self.get_r53zone(zone)
113
        else:
114
            del self.credentials['region']
115
            obj = getattr(module, cls)(**self.credentials)
116
117
        if not obj:
118
            raise ValueError('Invalid or missing credentials (aws_access_key_id,'
119
                             'aws_secret_access_key) or region')
120
121
        resultset = getattr(obj, action)(**kwargs)
122
        formatted = self.resultsets.formatter(resultset)
123
        return formatted if isinstance(formatted, list) else [formatted]
124
125
    def do_function(self, module_path, action, **kwargs):
126
        module = __import__(module_path)
127
        return getattr(module, action)(**kwargs)
128