blob: 6f3f56c656696853653c96dd12150150ccf33255 [file] [log] [blame]
Oleksiy Petrenko5bfb8bc2018-08-23 15:08:17 +03001import functools
Oleksiy Petrenkocaad2032018-04-20 14:42:46 +03002import logging
3import os_client_config
Vasyl Saienkocb788d42018-09-26 10:34:50 +00004import time
Oleksiy Petrenkocaad2032018-04-20 14:42:46 +03005
Oleh Hryhorov4ce5d2c2018-11-08 18:41:20 +02006from salt.exceptions import CommandExecutionError
7
Oleksiy Petrenkocaad2032018-04-20 14:42:46 +03008log = logging.getLogger(__name__)
9
10NEUTRON_VERSION_HEADER = 'x-openstack-networking-version'
11ADAPTER_VERSION = '2.0'
12
13
14class NeutronException(Exception):
15
16 _msg = "Neutron module exception occured."
17
18 def __init__(self, message=None, **kwargs):
19 super(NeutronException, self).__init__(message or self._msg)
20
21
22class NoNeutronEndpoint(NeutronException):
23 _msg = "Neutron endpoint not found in keystone catalog."
24
25
26class NoAuthPluginConfigured(NeutronException):
27 _msg = ("You are using keystoneauth auth plugin that does not support "
28 "fetching endpoint list from token (noauth or admin_token).")
29
30
31class NoCredentials(NeutronException):
32 _msg = "Please provide cloud name present in clouds.yaml."
33
34
35class ResourceNotFound(NeutronException):
36 _msg = "Uniq resource: {resource} with name: {name} not found."
37
38 def __init__(self, resource, name, **kwargs):
39 super(NeutronException, self).__init__(
40 self._msg.format(resource=resource, name=name))
41
42
43class MultipleResourcesFound(NeutronException):
44 _msg = "Multiple resource: {resource} with name: {name} found."
45
46 def __init__(self, resource, name, **kwargs):
47 super(NeutronException, self).__init__(
48 self._msg.format(resource=resource, name=name))
49
50
51def _get_raw_client(cloud_name):
52 service_type = 'network'
53 config = os_client_config.OpenStackConfig()
54 cloud = config.get_one_cloud(cloud_name)
55 adapter = cloud.get_session_client(service_type)
56 adapter.version = ADAPTER_VERSION
57 try:
58 access_info = adapter.session.auth.get_access(adapter.session)
59 access_info.service_catalog.get_endpoints()
60 except (AttributeError, ValueError):
61 e = NoAuthPluginConfigured()
62 log.exception('%s' % e)
63 raise e
64 return adapter
65
66
67def send(method):
68 def wrap(func):
Oleksiy Petrenko5bfb8bc2018-08-23 15:08:17 +030069 @functools.wraps(func)
Oleksiy Petrenkocaad2032018-04-20 14:42:46 +030070 def wrapped_f(*args, **kwargs):
71 cloud_name = kwargs.pop('cloud_name')
Vasyl Saienko65fb5d32018-10-24 12:51:51 +000072 connect_retries = 30
Vasyl Saienkocb788d42018-09-26 10:34:50 +000073 connect_retry_delay = 1
Oleksiy Petrenkocaad2032018-04-20 14:42:46 +030074 if not cloud_name:
75 e = NoCredentials()
76 log.error('%s' % e)
77 raise e
78 adapter = _get_raw_client(cloud_name)
79 # Remove salt internal kwargs
80 kwarg_keys = list(kwargs.keys())
81 for k in kwarg_keys:
82 if k.startswith('__'):
83 kwargs.pop(k)
84 url, request_kwargs = func(*args, **kwargs)
85 if 'microversion' in kwargs:
86 request_kwargs['headers'][
87 NEUTRON_VERSION_HEADER] = kwargs['microversion']
Vasyl Saienko65fb5d32018-10-24 12:51:51 +000088 response = None
Vasyl Saienkocb788d42018-09-26 10:34:50 +000089 for i in range(connect_retries):
90 try:
91 response = getattr(adapter, method)(
92 url, connect_retries=connect_retries,
93 **request_kwargs)
94 except Exception as e:
95 if hasattr(e, 'http_status') and (e.http_status >= 500
96 or e.http_status == 0):
97 msg = ("Got retriable exception when contacting "
98 "Neutron API. Sleeping for %ss. Attepmpts "
99 "%s of %s")
100 log.error(msg % (connect_retry_delay, i, connect_retries))
101 time.sleep(connect_retry_delay)
102 continue
103 break
Vasyl Saienko65fb5d32018-10-24 12:51:51 +0000104 if not response or not response.content:
Oleksiy Petrenkocaad2032018-04-20 14:42:46 +0300105 return {}
106 try:
107 resp = response.json()
108 except ValueError:
109 resp = response.content
110 return resp
111 return wrapped_f
112 return wrap
Oleh Hryhorov4ce5d2c2018-11-08 18:41:20 +0200113
114def wait_for_api_ready(cloud_name, retries=1, retry_timeout=10, **kwargs):
115
116 adapter = _get_raw_client(cloud_name)
117 response = None
118 for i in range(1, retries+1):
119 try:
120 response = getattr(adapter, 'get')(
121 '/', connect_retries=retries,
122 **kwargs)
123 except Exception as e:
124 msg = ("Error: %s "
125 "Sleeping for %ss. "
126 "Attempts %s of %s ")
127 log.error(msg % (e, retry_timeout, i, retries))
128 time.sleep(retry_timeout)
129 continue
130 break
131 if not response or not response.content:
132 if e:
133 raise CommandExecutionError(e)
134 else:
135 return {}
136 try:
137 resp = response.json()
138 except ValueError:
139 resp = response.content
140 return resp
141