blob: aaed6fd0a86aef0d05c714cc2315277042e23f4d [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
Vasyl Saienko0291d9c2018-05-31 12:44:07 +03004import functools
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +03005
Jiri Broulik47aa6b32017-07-10 18:39:15 +02006LOG = logging.getLogger(__name__)
7
8# Import third party libs
9HAS_CINDER = False
10try:
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030011 from cinderclient.client import Client
Jiri Broulik47aa6b32017-07-10 18:39:15 +020012 HAS_CINDER = True
13except ImportError:
14 pass
15
16__opts__ = {}
17
18
19def __virtual__():
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030020 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020021 Only load this module if cinder
22 is installed on this minion.
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030023 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020024 if HAS_CINDER:
25 return 'cinderng'
26 return False
27
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030028
Jiri Broulik47aa6b32017-07-10 18:39:15 +020029def _authng(profile=None):
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030030 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020031 Set up cinder credentials
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030032 """
Jiri Broulik47aa6b32017-07-10 18:39:15 +020033 credentials = {
34 'username': profile['user'],
35 'password': profile['password'],
36 'project_id': profile['project_id'],
Oleg Iurchenko6fe8e5d2018-02-20 14:26:04 +020037 'auth_url': "{}://{}:{}/{}".format(
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030038 profile['protocol'],
39 profile['host'],
Oleg Iurchenko6fe8e5d2018-02-20 14:26:04 +020040 profile['port'],
41 profile.get('api_version', 'v3')
Denis V. Meltsaykin6b1fa432017-09-18 16:49:53 +030042 ),
Jiri Broulik47aa6b32017-07-10 18:39:15 +020043 'endpoint_type': profile['endpoint_type'],
44 'certificate': profile['certificate'],
Oleg Iurchenko86bf9e42018-01-18 20:58:21 +020045 'region_name': profile['region_name'],
46 'retries': profile.get('retries', 5)
Jiri Broulik47aa6b32017-07-10 18:39:15 +020047 }
48 return credentials
49
Oleh Hryhorov49c4b492018-05-03 16:07:39 +030050def retries(func):
Vasyl Saienko0291d9c2018-05-31 12:44:07 +030051 @functools.wraps(func)
Oleh Hryhorov49c4b492018-05-03 16:07:39 +030052 def func_wrapper(*args, **kwargs):
Oleh Hryhorovc4398b22018-05-29 13:12:08 +030053 retries = kwargs.get('retries', 5)
Oleh Hryhorov49c4b492018-05-03 16:07:39 +030054 timeout = kwargs.get('timeout', 5)
55 res = None
56 for i in range(retries):
57 try:
Vasyl Saienko0291d9c2018-05-31 12:44:07 +030058 return func(*args, **kwargs)
Oleh Hryhorov49c4b492018-05-03 16:07:39 +030059 except Exception as e:
60 if i == retries - 1:
61 raise e
Oleh Hryhorov49c4b492018-05-03 16:07:39 +030062 else:
Vasyl Saienko0291d9c2018-05-31 12:44:07 +030063 time.sleep(timeout)
Oleh Hryhorov49c4b492018-05-03 16:07:39 +030064 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'