def acquire_connection(self, auto_login=True, headers=None, rid=-1): '''Check out an available HTTPConnection instance. Blocks until a connection is available. :auto_login: automatically logins before returning conn :headers: header to pass on to login attempt :param rid: request id passed in from request eventlet. :returns: An available HTTPConnection instance or None if no api_providers are configured. ''' if self._conn_pool.empty(): LOG.debug("[%d] Waiting to acquire API client connection.", rid) priority, conn = self._conn_pool.get() now = time.time() if getattr(conn, 'last_used', now) < now - self.CONN_IDLE_TIMEOUT: LOG.info(_LI("[%(rid)d] Connection %(conn)s idle for " "%(sec)0.2f seconds; reconnecting."), {'rid': rid, 'conn': api_client.ctrl_conn_to_str(conn), 'sec': now - conn.last_used}) conn = self._create_connection(*self._conn_params(conn)) self.set_auth_cookie(conn, None) conn.last_used = now conn.priority = priority # stash current priority for release qsize = self._conn_pool.qsize() LOG.debug("[%(rid)d] Acquired connection %(conn)s. %(qsize)d " "connection(s) available.", {'rid': rid, 'conn': api_client.ctrl_conn_to_str(conn), 'qsize': qsize}) if auto_login and self.auth_cookie(conn) is None: self._wait_for_login(conn, headers) return conn
def run(self): while True: try: if self._stopped: # Gracefully terminate this thread if the _stopped # attribute was set to true LOG.info(_LI("Stopping TaskManager")) break # get a task from queue, or timeout for periodic status check task = self._get_task() try: #if constants.TaskStatus.ROLLBACK == task.status: self._main_thread_exec_task = task self._execute(task) finally: self._main_thread_exec_task = None if task.status in [ constants.TaskStatus.NONE, constants.TaskStatus.ERROR, constants.TaskStatus.COMPLETED ]: # The thread is killed during _execute(). To guarantee # the task been aborted correctly, put it to the queue. #self._enqueue(task) self._dequeue(task) else: self._enqueue(task) except Exception: LOG.exception( _LE("TaskManager terminating because " "of an exception")) break
def get_vifs_by_ids(self, port_ids): interface_info = self.get_ports_attributes( "Interface", columns=["name", "external_ids", "ofport"], if_exists=True) by_id = {} for x in interface_info: external_ids = self._format_attr(x['external_ids']) if x['name'] in consts.FTNT_PORTS and \ isinstance(external_ids.get('iface-id'), dict): if_ids = set(external_ids.get('iface-id')) by_id.update({if_id: x for if_id in if_ids}) elif x['name'] not in consts.FTNT_PORTS: by_id.update({external_ids.get('iface-id'): x}) result = {} for port_id in port_ids: result[port_id] = None if port_id not in by_id: LOG.info(_LI("Port %(port_id)s not present in bridge " "%(br_name)s"), {'port_id': port_id, 'br_name': self.br_name}) continue pinfo = by_id[port_id] if not self._check_ofport(port_id, pinfo): continue mac = pinfo['external_ids'].get('attached-mac') result[port_id] = ovs_lib.VifPort(pinfo['name'], pinfo['ofport'], port_id, mac, self) return result
def run(self): while True: try: if self._stopped: # Gracefully terminate this thread if the _stopped # attribute was set to true LOG.info(_LI("Stopping TaskManager")) break # get a task from queue, or timeout for periodic status check task = self._get_task() try: #if constants.TaskStatus.ROLLBACK == task.status: self._main_thread_exec_task = task self._execute(task) finally: self._main_thread_exec_task = None if task.status in [constants.TaskStatus.NONE, constants.TaskStatus.ERROR, constants.TaskStatus.COMPLETED]: # The thread is killed during _execute(). To guarantee # the task been aborted correctly, put it to the queue. #self._enqueue(task) self._dequeue(task) else: self._enqueue(task) except Exception: LOG.exception(_LE("TaskManager terminating because " "of an exception")) break
def stop(self): if self._thread is None: return self._stopped = True self._thread.kill() self._thread = None # Stop looping call and abort running tasks self._monitor.stop() if self._monitor_busy: self._monitor.wait() self._abort() LOG.info(_LI("TaskManager terminated"))
def update_network_precommit(self, mech_context): """Noop now, it is left here for future.""" cur_network = mech_context.current org_network = mech_context.original if cur_network["router:external"] != org_network["router:external"]: LOG.info(_LI("update_network_precommit failed: the external " "attribute cannot be updated, instead of updating the" " attribute, the external network only support " "creation from scratch on the admin view. \nThe " "org_network: %(org)s, \nthe cur_network %(cur)s"), {'org': org_network, 'cur': cur_network}) raise NotImplementedError("The external attribute cannot be " "updated") pass
def get_vif_port_by_id(self, port_id): ports = self.ovsdb.db_find( 'Interface', ('external_ids', '=', {'iface-id': port_id}), ('external_ids', '!=', {'attached-mac': ''}), columns=['external_ids', 'name', 'ofport']).execute() for port in ports: if self.br_name != self.get_bridge_for_iface(port['name']): continue if not self._check_ofport(port_id, port): continue mac = port['external_ids'].get('attached-mac') return ovs_lib.VifPort(port['name'], port['ofport'], port_id, mac, self) #import ipdb;ipdb.set_trace() LOG.info(_LI("Port %(port_id)s not present in bridge %(br_name)s"), {'port_id': port_id, 'br_name': self.br_name})
def delete_network_postcommit(self, mech_context): """Delete network which translates to remove vlan interface and related vdom from the fortigate. """ LOG.debug("delete_network_postcommit: called") network = mech_context.current context = mech_context._plugin_context tenant_id = network['tenant_id'] with context.session.begin(subtransactions=True): try: utils.delete_vdom(self, context, tenant_id=tenant_id) LOG.info(_LI("delete network postcommit: tenant= %(tenant_id)s" " network= %(network)s"), {'tenant_id': tenant_id, 'network': network}) except Exception as e: resources.Exinfo(e) raise ml2_exc.MechanismDriverError( method=sys._getframe().f_code.co_name)
def _issue_request(self): '''Issue a request to a provider.''' conn = self.get_conn() if conn is None: error = Exception(_("No API connections available")) self._request_error = error return error url = self._url LOG.debug("[%(rid)d] Issuing - request url: %(conn)s, body: %(body)s", {'rid': self._rid(), 'conn': self._request_str(conn, url), 'body': self._body}) issued_time = time.time() is_conn_error = False is_conn_service_unavail = False response = None try: redirects = 0 while redirects <= self._redirects: # Update connection with user specified request timeout, # the connect timeout is usually smaller so we only set # the request timeout after a connection is established if conn.sock is None: conn.connect() conn.sock.settimeout(self._http_timeout) elif conn.sock.gettimeout() != self._http_timeout: conn.sock.settimeout(self._http_timeout) headers = copy.copy(self._headers) if templates.RELOGIN in url: url = jsonutils.loads(templates.LOGIN)['path'] conn.connect() self._api_client._wait_for_login(conn, headers) url = self._url cookie = self._api_client.auth_cookie(conn) if (self._url != jsonutils.loads(templates.LOGIN)['path'] and cookie): headers['Cookie'] = cookie['Cookie'] headers['X-CSRFTOKEN'] = cookie['X-CSRFTOKEN'] try: if self._body: if (self._url == jsonutils.loads(templates.LOGIN)['path']): body = urlparse.urlencode(self._body) else: body = jsonutils.dumps(self._body) else: body = None LOG.debug("Issuing request: self._method = [%(method)s], " "url= %(url)s, body=%(body)s, " "headers=%(headers)s", {'method': self._method, "url": url, "body": body, "headers": headers}) conn.request(self._method, url, body, headers) except Exception as e: with excutils.save_and_reraise_exception(): LOG.warning( _LW("[%(rid)d] Exception issuing request: %(e)s"), {'rid': self._rid(), 'e': e}) response = conn.getresponse() response.body = response.read() response.headers = response.getheaders() elapsed_time = time.time() - issued_time LOG.debug("@@@@@@ [ _issue_request ] [%(rid)d] " "Completed request '%(conn)s': " "%(status)s (%(elapsed)s seconds), " "response.headers %(response.headers)s, " "response.body %(response.body)s", {'rid': self._rid(), 'conn': self._request_str(conn, url), 'status': response.status, 'elapsed': elapsed_time, 'response.headers': response.headers, 'response.body': response.body}) if response.status in (401, 302): if (cookie is None and self._url != jsonutils.loads(templates.LOGIN)['path']): # The connection still has no valid cookie despite # attempts to authenticate and the request has failed # with unauthorized status code. If this isn't a # a request to authenticate, we should abort the # request since there is no point in retrying. self._abort = True # If request is unauthorized, clear the session cookie # for the current provider so that subsequent requests # to the same provider triggers re-authentication. self._api_client.set_auth_cookie(conn, None) elif 503 == response.status: is_conn_service_unavail = True if response.status not in [301, 307]: break elif redirects >= self._redirects: LOG.info(_LI("[%d] Maximum redirects exceeded, aborting " "request"), self._rid()) break redirects += 1 conn, url = self._redirect_params(conn, response.headers, self._client_conn is None) if url is None: response.status = 500 break LOG.info(_LI("[%(rid)d] Redirecting request to: %(conn)s"), {'rid': self._rid(), 'conn': self._request_str(conn, url)}) # yield here, just in case we are not out of the loop yet eventlet.greenthread.sleep(0) # If we receive any of these responses, then # our server did not process our request and may be in an # errored state. Raise an exception, which will cause the # the conn to be released with is_conn_error == True # which puts the conn on the back of the client's priority # queue. if 500 == response.status or 501 < response.status: LOG.warning(_LW("[%(rid)d] Request '%(method)s %(url)s' " "received: %(status)s"), {'rid': self._rid(), 'method': self._method, 'url': self._url, 'status': response.status}) raise Exception(_('Server error return: %s'), response.status) return response except Exception as e: if isinstance(e, httpclient.BadStatusLine): msg = ("Invalid server response") else: msg = str(e) if response is None: elapsed_time = time.time() - issued_time LOG.warning(_LW("[%(rid)d] Failed request '%(conn)s': '%(msg)s' " "(%(elapsed)s seconds)"), {'rid': self._rid(), 'conn': self._request_str(conn, url), 'msg': msg, 'elapsed': elapsed_time}) self._request_error = e is_conn_error = True return e finally: # Make sure we release the original connection provided by the # acquire_connection() call above. if self._client_conn is None: self._api_client.release_connection(conn, is_conn_error, is_conn_service_unavail, rid=self._rid())