blob: 4d75116689ab0c37e3148b55447582da1e8d94ee [file] [log] [blame]
Jiri Broulik47aa6b32017-07-10 18:39:15 +02001# -*- coding: utf-8 -*-
2import logging
Oleh Hryhorov49c4b492018-05-03 16:07:39 +03003import time
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +03004
Jiri Broulik47aa6b32017-07-10 18:39:15 +02005LOG = logging.getLogger(__name__)
6
7# Import third party libs
8HAS_CINDER = False
9try:
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030010 from cinderclient.client import Client
Jiri Broulik47aa6b32017-07-10 18:39:15 +020011 HAS_CINDER = True
12except ImportError:
13 pass
14
15__opts__ = {}
16
17
18def __virtual__():
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030019 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020020 Only load this module if cinder
21 is installed on this minion.
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030022 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020023 if HAS_CINDER:
24 return 'cinderng'
25 return False
26
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030027
Jiri Broulik47aa6b32017-07-10 18:39:15 +020028def _authng(profile=None):
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030029 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020030 Set up cinder credentials
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030031 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020032 credentials = {
33 'username': profile['user'],
34 'password': profile['password'],
35 'project_id': profile['project_id'],
Oleg Iurchenko6fe8e5d2018-02-20 14:26:04 +020036 'auth_url': "{}://{}:{}/{}".format(
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030037 profile['protocol'],
38 profile['host'],
Oleg Iurchenko6fe8e5d2018-02-20 14:26:04 +020039 profile['port'],
40 profile.get('api_version', 'v3')
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030041 ),
Jiri Broulik47aa6b32017-07-10 18:39:15 +020042 'endpoint_type': profile['endpoint_type'],
43 'certificate': profile['certificate'],
Oleg Iurchenko86bf9e42018-01-18 20:58:21 +020044 'region_name': profile['region_name'],
45 'retries': profile.get('retries', 5)
Jiri Broulik47aa6b32017-07-10 18:39:15 +020046 }
47 return credentials
48
Oleh Hryhorov49c4b492018-05-03 16:07:39 +030049def retries(func):
50 def func_wrapper(*args, **kwargs):
51 retries = kwargs.get('retries', 3)
52 timeout = kwargs.get('timeout', 5)
53 res = None
54 for i in range(retries):
55 try:
56 res = func(*args, **kwargs)
57 except Exception as e:
58 if i == retries - 1:
59 raise e
60 time.sleep(timeout)
61 else:
62 break
63 return res
64 return func_wrapper
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030065
Jiri Broulik47aa6b32017-07-10 18:39:15 +020066def create_conn(cred=None):
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030067 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020068 create connection
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030069 """
70 nt = Client(
71 '2',
72 username=cred['username'],
73 api_key=cred['password'],
74 project_id=cred['project_id'],
75 auth_url=cred['auth_url'],
76 endpoint_type=cred['endpoint_type'],
77 cacert=cred['certificate'],
Oleg Iurchenko86bf9e42018-01-18 20:58:21 +020078 region_name=cred['region_name'],
79 retries=cred['retries']
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030080 )
Jiri Broulik47aa6b32017-07-10 18:39:15 +020081 return nt
82
Oleh Hryhorov49c4b492018-05-03 16:07:39 +030083@retries
Jiri Broulik47aa6b32017-07-10 18:39:15 +020084def list_volumes(profile=None, **kwargs):
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030085 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020086 Return list of cinder volumes.
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030087 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020088 cred = _authng(profile)
89 nt = create_conn(cred)
90 return nt.volumes.list()
91
Oleh Hryhorov49c4b492018-05-03 16:07:39 +030092@retries
Jiri Broulik47aa6b32017-07-10 18:39:15 +020093def list_volume_type(profile=None, **kwargs):
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030094 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020095 Return list of volume types
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030096 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020097 cred = _authng(profile)
98 nt = create_conn(cred)
99 return nt.volume_types.list()
100
Oleh Hryhorov49c4b492018-05-03 16:07:39 +0300101@retries
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200102def get_volume_type(type_name, profile=None, **kwargs):
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +0300103 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200104 Returns id of the specified volume type name
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +0300105 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200106 vt_id = None
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +0300107 vt_list = list_volume_type(profile)
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200108 for vt in vt_list:
109 if vt.name == type_name:
110 vt_id = vt.id
111
112 if vt_id:
113 cred = _authng(profile)
114 nt = create_conn(cred)
115 try:
116 vt = nt.volume_types.get(vt_id)
117 return vt
118 except:
119 return
120 else:
121 return
122
Oleh Hryhorov49c4b492018-05-03 16:07:39 +0300123@retries
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200124def create_volume_type(type_name, profile=None, **kwargs):
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +0300125 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200126 Create cinder volume type
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +0300127 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200128 vt = get_volume_type(type_name, profile)
129 if not vt:
130 cred = _authng(profile)
131 nt = create_conn(cred)
132 try:
133 nt.volume_types.create(type_name)
134 return 'created'
135 except:
136 return 'failed'
137 else:
138 return 'exists'
139
Oleh Hryhorov49c4b492018-05-03 16:07:39 +0300140@retries
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200141def get_keys_volume_type(type_name, profile=None, **kwargs):
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +0300142 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200143 Return extra specs of the specified volume type.
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +0300144 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200145
146 vt = get_volume_type(type_name, profile)
147 if vt:
148 try:
149 return vt.get_keys()
150 except:
151 return 'failed'
152 else:
153 return
154
Oleh Hryhorov49c4b492018-05-03 16:07:39 +0300155@retries
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200156def set_keys_volume_type(type_name, keys={}, profile=None, **kwargs):
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +0300157 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200158 Set extra specs of the specified volume type.
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +0300159 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +0200160 set_keys = False
161 vt = get_volume_type(type_name, profile)
162 if vt:
163 k = get_keys_volume_type(type_name, profile)
164 if not k:
165 set_keys = True
166 elif k:
167 for key in keys:
168 if k.get(key) != keys[key]:
169 set_keys = True
170 elif len(k) != len(keys):
171 set_keys = True
172 else:
173 return
174
175 if set_keys:
176 try:
177 vt.set_keys(keys)
178 return 'updated'
179 except:
180 return 'failed'
181 else:
182 return 'exist'
183 else:
184 return 'not found'