def _proxy_request(self, request): LOG.debug("Request: %s", request) port_profile_id = self._get_port_profile_id(request) if not port_profile_id: return webob.exc.HTTPNotFound() headers = self._get_headers(port_profile_id) if not headers: return webob.exc.HTTPNotFound() LOG.debug("Trying to proxy the request.") nova_url = '%s:%s' % (CONF.nova_metadata_host, CONF.nova_metadata_port) allow_insecure = CONF.nova_metadata_insecure http_request = httplib2.Http( ca_certs=CONF.auth_ca_cert, disable_ssl_certificate_validation=allow_insecure) if CONF.nova_client_cert and CONF.nova_client_priv_key: http_request.add_certificate(key=CONF.nova_client_priv_key, cert=CONF.nova_client_cert, domain=nova_url) url = urlparse.urlunsplit( (CONF.nova_metadata_protocol, nova_url, request.path_info, request.query_string, '')) response, content = http_request.request(url.replace( port_profile_id, ""), method=request.method, headers=headers, body=request.body) LOG.debug("Response [%s]: %s", response.status, content) if response.status == 200: request.response.content_type = response['content-type'] request.response.body = content return request.response elif response.status == 403: LOG.warning('The remote metadata server responded with Forbidden. ' 'This response usually occurs when shared secrets do ' 'not match.') return webob.exc.HTTPForbidden() elif response.status == 400: return webob.exc.HTTPBadRequest() elif response.status == 404: return webob.exc.HTTPNotFound() elif response.status == 409: return webob.exc.HTTPConflict() elif response.status == 500: message = _( "Remote metadata server experienced an internal server error.") LOG.warning(message) return webob.exc.HTTPInternalServerError(explanation=message) else: message = _("The HNV Metadata proxy experienced an internal" " server error.") LOG.warning('Unexpected response code: %s', response.status) return webob.exc.HTTPInternalServerError(explanation=message)
def _provision_network(self, port_id, net_uuid, network_type, physical_network, segmentation_id): """Provision the network with the received information.""" LOG.info("Provisioning network %s", net_uuid) vswitch_name = self._get_vswitch_name(network_type, physical_network) if network_type == h_constant.TYPE_VLAN: # Nothing to do pass elif network_type == h_constant.TYPE_FLAT: # Nothing to do pass elif network_type == h_constant.TYPE_LOCAL: # TODO(alexpilotti): Check that the switch type is private # or create it if not existing. pass elif network_type == h_constant.TYPE_NVGRE and self._nvgre_enabled: self._nvgre_ops.bind_nvgre_network(segmentation_id, net_uuid, vswitch_name) else: raise exception.NetworkingHyperVException( (_("Cannot provision unknown network type " "%(network_type)s for network %(net_uuid)s") % dict(network_type=network_type, net_uuid=net_uuid))) vswitch_map = { 'network_type': network_type, 'vswitch_name': vswitch_name, 'ports': [], 'vlan_id': segmentation_id} self._network_vswitch_map[net_uuid] = vswitch_map
def __call__(self, req): try: return self._proxy_request(req) except Exception: LOG.exception("Unexpected error.") msg = _('An unknown error has occurred. ' 'Please try your request again.') explanation = six.text_type(msg) return webob.exc.HTTPInternalServerError(explanation=explanation)
def _validate_vswitches(self): vswitch_names = list(self._physical_network_mappings.values()) if self._local_network_vswitch: vswitch_names.append(self._local_network_vswitch) vswitches_valid = True for vswitch_name in vswitch_names: try: self._validate_vswitch(vswitch_name) except exception.ValidationError: # We're validating all the vSwitches before erroring out. LOG.error("Validating vSwitch %s failed", vswitch_name) vswitches_valid = False # We're currently stopping the service if any of the configured # vSwitches are unavailable. if not vswitches_valid: err_msg = _("Validating one or more configured vSwitches failed.") raise exception.ValidationError(err_msg) elif not vswitch_names: err_msg = _("No vSwitch configured.") raise exception.ValidationError(err_msg)
def _validate_vswitch(self, vswitch_name): try: vswitch_extensions = self._utils.get_vswitch_extensions( vswitch_name) except os_win_exc.HyperVvSwitchNotFound as exc: raise exception.ValidationError(exc.message) for ext in vswitch_extensions: if (self._is_ovs_extension(ext) and ext['enabled_state'] == os_win_const.CIM_STATE_ENABLED): err_msg = _("The Open vSwitch extension is enabled on the " "'%s' vSwitch. For this reason, this agent " "cannot use the specified vSwitch.") raise exception.ValidationError(err_msg % vswitch_name)
def _get_vswitch_name(self, network_type, physical_network): """Get the vswitch name for the received network information.""" if network_type != constants.TYPE_LOCAL: vswitch_name = self._get_vswitch_for_physical_network( physical_network) else: vswitch_name = self._local_network_vswitch if vswitch_name: return vswitch_name err_msg = _("No vSwitch configured for physical network " "'%(physical_network)s'. Neutron network type: " "'%(network_type)s'.") raise exception.NetworkingHyperVException( err_msg % dict(physical_network=physical_network, network_type=network_type))
def _init_nvgre(self): # if NVGRE is enabled, self._nvgre_ops is required in order to properly # set the agent state (see get_agent_configrations method). if not CONF.NVGRE.enable_support: return if not CONF.NVGRE.provider_tunnel_ip: err_msg = _('enable_nvgre_support is set to True, but ' 'provider tunnel IP is not configured. ' 'Check neutron.conf config file.') LOG.error(err_msg) raise exception.NetworkingHyperVException(err_msg) self._nvgre_enabled = True self._nvgre_ops = nvgre_ops.HyperVNvgreOps( list(self._physical_network_mappings.values())) self._nvgre_ops.init_notifier(self._context, self._client) self._nvgre_ops.tunnel_update(self._context, CONF.NVGRE.provider_tunnel_ip, h_constant.TYPE_NVGRE)
HYPERV_AGENT_GROUP_NAME = 'AGENT' HYPERV_AGENT_GROUP = cfg.OptGroup( HYPERV_AGENT_GROUP_NAME, title='Hyper-V Neutron Agent Options', help=('Configuration options for the neutron-hyperv-agent (L2 agent).') ) HYPERV_AGENT_OPTS = [ cfg.ListOpt( 'physical_network_vswitch_mappings', default=[], help=_('List of <physical_network>:<vswitch> ' 'where the physical networks can be expressed with ' 'wildcards, e.g.: ."*:external"')), cfg.StrOpt( 'local_network_vswitch', default='private', help=_('Private vswitch name used for local networks')), cfg.IntOpt('polling_interval', default=2, min=1, help=_("The number of seconds the agent will wait between " "polling for local device changes.")), cfg.IntOpt('worker_count', default=10, min=1, help=_("The number of worker threads allowed to run in " "parallel to process port binding.")), cfg.IntOpt('worker_retry', default=3, min=0, help=_("The number of times worker process will retry " "port binding.")), cfg.BoolOpt('enable_metrics_collection',