def test_urlsplit_ipv6(self): ipv6_url = 'http://[::1]:443/v2.0/' result = netutils.urlsplit(ipv6_url) self.assertEqual(result.scheme, 'http') self.assertEqual(result.netloc, '[::1]:443') self.assertEqual(result.path, '/v2.0/') self.assertEqual(result.hostname, '::1') self.assertEqual(result.port, 443) ipv6_url = 'http://*****:*****@[::1]/v2.0/' result = netutils.urlsplit(ipv6_url) self.assertEqual(result.scheme, 'http') self.assertEqual(result.netloc, 'user:pass@[::1]') self.assertEqual(result.path, '/v2.0/') self.assertEqual(result.hostname, '::1') self.assertEqual(result.port, None) ipv6_url = 'https://[2001:db8:85a3::8a2e:370:7334]:1234/v2.0/xy?ab#12' result = netutils.urlsplit(ipv6_url) self.assertEqual(result.scheme, 'https') self.assertEqual(result.netloc, '[2001:db8:85a3::8a2e:370:7334]:1234') self.assertEqual(result.path, '/v2.0/xy') self.assertEqual(result.hostname, '2001:db8:85a3::8a2e:370:7334') self.assertEqual(result.port, 1234) self.assertEqual(result.query, 'ab') self.assertEqual(result.fragment, '12')
def update_actions(self, old_alarm=None): trustor_user_id = pecan.request.headers.get('X-User-Id') trustor_project_id = pecan.request.headers.get('X-Project-Id') roles = pecan.request.headers.get('X-Roles', '') if roles: roles = roles.split(',') else: roles = [] auth_plugin = pecan.request.environ.get('keystone.token_auth') for actions in (self.ok_actions, self.alarm_actions, self.insufficient_data_actions): if actions is not None: for index, action in enumerate(actions[:]): url = netutils.urlsplit(action) if self._is_trust_url(url): if '@' not in url.netloc: # We have a trust action without a trust ID, # create it trust_id = keystone_client.create_trust_id( trustor_user_id, trustor_project_id, roles, auth_plugin) netloc = '%s:delete@%s' % (trust_id, url.netloc) url = list(url) url[1] = netloc actions[index] = urlparse.urlunsplit(url) if old_alarm: for key in ('ok_actions', 'alarm_actions', 'insufficient_data_actions'): for action in getattr(old_alarm, key): url = netutils.urlsplit(action) if (self._is_trust_url(url) and url.password and action not in getattr(self, key)): keystone_client.delete_trust_id( url.username, auth_plugin)
def test_publish_with_none_rabbit_driver(self, cgt): sample_publisher = msg_publisher.SampleNotifierPublisher( self.CONF, netutils.urlsplit('notifier://127.0.0.1:9092?driver=kafka')) cgt.assert_called_with(self.CONF, 'kafka://127.0.0.1:9092') transport = oslo_messaging.get_transport(self.CONF, 'kafka://127.0.0.1:9092') self.assertIsInstance(transport._driver, kafka_driver.KafkaDriver) side_effect = msg_publisher.DeliveryFailure() with mock.patch.object(sample_publisher, '_send') as fake_send: fake_send.side_effect = side_effect self.assertRaises( msg_publisher.DeliveryFailure, sample_publisher.publish_samples, self.test_sample_data) self.assertEqual(0, len(sample_publisher.local_queue)) self.assertEqual(100, len(fake_send.mock_calls)) fake_send.assert_called_with('metering', mock.ANY) event_publisher = msg_publisher.EventNotifierPublisher( self.CONF, netutils.urlsplit('notifier://127.0.0.1:9092?driver=kafka')) cgt.assert_called_with(self.CONF, 'kafka://127.0.0.1:9092') with mock.patch.object(event_publisher, '_send') as fake_send: fake_send.side_effect = side_effect self.assertRaises( msg_publisher.DeliveryFailure, event_publisher.publish_events, self.test_event_data) self.assertEqual(0, len(event_publisher.local_queue)) self.assertEqual(100, len(fake_send.mock_calls)) fake_send.assert_called_with('event', mock.ANY)
def _parse_resource(res): """Parse resource from discovery. Either URL can be given or dict. Dict has to contain at least keys 'resource_id' and 'resource_url', all the dict keys will be stored as metadata. :param res: URL or dict containing all resource info. :return parsed_url, resource_id, metadata: Returns parsed URL used for SNMP query, unique identifier of the resource and metadata of the resource. """ if isinstance(res, dict): if 'resource_url' not in res or 'resource_id' not in res: LOG.exception(_('Passed resource dict must contain keys ' 'resource_id and resource_url.')) metadata = res parsed_url = netutils.urlsplit(res['resource_url']) resource_id = res['resource_id'] else: metadata = {} parsed_url = netutils.urlsplit(res) resource_id = res return parsed_url, resource_id, metadata
def test_urlsplit(self): result = netutils.urlsplit('rpc://myhost?someparam#somefragment') self.assertEqual(result.scheme, 'rpc') self.assertEqual(result.netloc, 'myhost') self.assertEqual(result.path, '') self.assertEqual(result.query, 'someparam') self.assertEqual(result.fragment, 'somefragment') result = netutils.urlsplit( 'rpc://myhost/mypath?someparam#somefragment', allow_fragments=False) self.assertEqual(result.scheme, 'rpc') self.assertEqual(result.netloc, 'myhost') self.assertEqual(result.path, '/mypath') self.assertEqual(result.query, 'someparam#somefragment') self.assertEqual(result.fragment, '') result = netutils.urlsplit( 'rpc://*****:*****@myhost/mypath?someparam#somefragment', allow_fragments=False) self.assertEqual(result.scheme, 'rpc') self.assertEqual(result.netloc, 'user:pass@myhost') self.assertEqual(result.path, '/mypath') self.assertEqual(result.query, 'someparam#somefragment') self.assertEqual(result.fragment, '')
def test_publish_other_host(self, cgt): msg_publisher.SampleNotifierPublisher( netutils.urlsplit('notifier://*****:*****@127.0.0.1:1234')) cgt.assert_called_with(self.CONF, 'rabbit://*****:*****@127.0.0.1:1234') msg_publisher.EventNotifierPublisher( netutils.urlsplit('notifier://*****:*****@127.0.0.1:1234')) cgt.assert_called_with(self.CONF, 'rabbit://*****:*****@127.0.0.1:1234')
def test_publish_to_host_without_policy(self): publisher = kafka.KafkaBrokerPublisher(self.CONF, netutils.urlsplit( 'kafka://127.0.0.1:9092?topic=ceilometer')) self.assertEqual('default', publisher.policy) publisher = kafka.KafkaBrokerPublisher(self.CONF, netutils.urlsplit( 'kafka://127.0.0.1:9092?topic=ceilometer&policy=test')) self.assertEqual('default', publisher.policy)
def parse_driver_info(node): """Parse the information required for Ironic to connect to iBMC. :param node: an Ironic node object :returns: dictionary of parameters :raises: InvalidParameterValue on malformed parameter(s) :raises: MissingParameterValue on missing parameter(s) """ driver_info = node.driver_info or {} missing_info = [key for key in REQUIRED_PROPERTIES if not driver_info.get(key)] if missing_info: raise exception.MissingParameterValue(_( 'Missing the following iBMC properties in node ' '%(node)s driver_info: %(info)s') % {'node': node.uuid, 'info': missing_info}) # Validate the iBMC address address = driver_info['ibmc_address'] parsed = netutils.urlsplit(address) if not parsed.scheme: address = 'https://%s' % address parsed = netutils.urlsplit(address) if not parsed.netloc: raise exception.InvalidParameterValue( _('Invalid iBMC address %(address)s set in ' 'driver_info/ibmc_address on node %(node)s') % {'address': address, 'node': node.uuid}) # Check if verify_ca is a Boolean or a file/directory in the file-system verify_ca = driver_info.get('ibmc_verify_ca', True) if isinstance(verify_ca, six.string_types): if not os.path.exists(verify_ca): try: verify_ca = strutils.bool_from_string(verify_ca, strict=True) except ValueError: raise exception.InvalidParameterValue( _('Invalid value type set in driver_info/' 'ibmc_verify_ca on node %(node)s. ' 'The value should be a Boolean or the path ' 'to a file/directory, not "%(value)s"' ) % {'value': verify_ca, 'node': node.uuid}) elif not isinstance(verify_ca, bool): raise exception.InvalidParameterValue( _('Invalid value type set in driver_info/ibmc_verify_ca ' 'on node %(node)s. The value should be a Boolean or the path ' 'to a file/directory, not "%(value)s"') % {'value': verify_ca, 'node': node.uuid}) return {'address': address, 'username': driver_info.get('ibmc_username'), 'password': driver_info.get('ibmc_password'), 'verify_ca': verify_ca}
def test_publish_other_host_vhost_and_query(self, cgt): msg_publisher.SampleNotifierPublisher( netutils.urlsplit('notifier://*****:*****@127.0.0.1:1234/foo' '?driver=amqp&amqp_auto_delete=true')) cgt.assert_called_with(self.CONF, 'amqp://*****:*****@127.0.0.1:1234/foo' '?amqp_auto_delete=true') msg_publisher.EventNotifierPublisher( netutils.urlsplit('notifier://*****:*****@127.0.0.1:1234/foo' '?driver=amqp&amqp_auto_delete=true')) cgt.assert_called_with(self.CONF, 'amqp://*****:*****@127.0.0.1:1234/foo' '?amqp_auto_delete=true')
def test_publish_topic_override(self, notifier): msg_publisher.SampleNotifierPublisher( netutils.urlsplit('notifier://?topic=custom_topic')) notifier.assert_called_with(mock.ANY, topic='custom_topic', driver=mock.ANY, retry=mock.ANY, publisher_id=mock.ANY) msg_publisher.EventNotifierPublisher( netutils.urlsplit('notifier://?topic=custom_event_topic')) notifier.assert_called_with(mock.ANY, topic='custom_event_topic', driver=mock.ANY, retry=mock.ANY, publisher_id=mock.ANY)
def test_auth_strategy(self, mock_method): host = ''.join(['snmp://*****:*****@foo?auth_proto=sha', '&priv_password=pass&priv_proto=aes256']) host = netutils.urlsplit(host) self.inspector._get_auth_strategy(host) mock_method.assert_called_with( 'a', authKey='b', authProtocol=snmp.cmdgen.usmHMACSHAAuthProtocol, privProtocol=snmp.cmdgen.usmAesCfb256Protocol, privKey='pass') host2 = 'snmp://*****:*****@foo?&priv_password=pass' host2 = netutils.urlsplit(host2) self.inspector._get_auth_strategy(host2) mock_method.assert_called_with('a', authKey='b', privKey='pass')
def test_create_event_workflow(self, fakeclient_cls): url = netutils.urlsplit("gnocchi://") self.publisher = gnocchi.GnocchiPublisher(self.conf.conf, url) fakeclient = fakeclient_cls.return_value now = timeutils.utcnow() self.useFixture(utils_fixture.TimeFixture(now)) expected_calls = [ mock.call.resource.create( 'instance', {'id': '9f9d01b9-4a58-4271-9e27-398b21ab20d1', 'user_id': '1e3ce043029547f1a61c1996d1a531a2', 'project_id': '7c150a59fe714e6f9263774af9688f0e', 'availability_zone': 'zone1', 'flavor_name': 'm1.tiny', 'flavor_id': '2', 'host': 'vagrant-precise'}), ] self.publisher.publish_events([INSTANCE_CREATE_END]) self.assertEqual(1, len(fakeclient.mock_calls)) for call in expected_calls: self.assertIn(call, fakeclient.mock_calls)
def test_broken_config_load(self, mylog): contents = [("---\n" "resources:\n" " - resource_type: foobar\n"), ("---\n" "resources:\n" " - resource_type: 0\n"), ("---\n" "resources:\n" " - sample_types: ['foo', 'bar']\n"), ("---\n" "resources:\n" " - sample_types: foobar\n" " - resource_type: foobar\n"), ] for content in contents: if six.PY3: content = content.encode('utf-8') temp = fileutils.write_to_tempfile(content=content, prefix='gnocchi_resources', suffix='.yaml') self.addCleanup(os.remove, temp) url = netutils.urlsplit( "gnocchi://?resources_definition_file=" + temp) d = gnocchi.GnocchiPublisher(self.conf.conf, url) self.assertTrue(mylog.error.called) self.assertEqual(0, len(d.resources_definition))
def test_published(self): self.data_sent = [] with mock.patch('socket.socket', self._make_fake_socket(self.data_sent)): publisher = udp.UDPPublisher( netutils.urlsplit('udp://somehost')) publisher.publish_samples(None, self.test_data) self.assertEqual(5, len(self.data_sent)) sent_counters = [] for data, dest in self.data_sent: counter = msgpack.loads(data) sent_counters.append(counter) # Check destination self.assertEqual(('somehost', self.CONF.collector.udp_port), dest) # Check that counters are equal self.assertEqual(sorted( [utils.meter_message_from_counter(d, "not-so-secret") for d in self.test_data]), sorted(sent_counters))
def test_published_with_policy_sized_queue_and_rpc_down(self): publisher = self.publisher_cls(netutils.urlsplit( '%s://?policy=queue&max_queue_length=3' % self.protocol)) side_effect = msg_publisher.DeliveryFailure() with mock.patch.object(publisher, '_send') as fake_send: fake_send.side_effect = side_effect for i in range(0, 5): for s in self.test_data: setattr(s, self.attr, 'test-%d' % i) getattr(publisher, self.pub_func)(mock.MagicMock(), self.test_data) self.assertEqual(3, len(publisher.local_queue)) self.assertEqual( 'test-2', publisher.local_queue[0][2][0][self.attr] ) self.assertEqual( 'test-3', publisher.local_queue[1][2][0][self.attr] ) self.assertEqual( 'test-4', publisher.local_queue[2][2][0][self.attr] )
def test_published_no_mock(self): publisher = msg_publisher.RPCPublisher( netutils.urlsplit('rpc://')) endpoint = mock.MagicMock(['record_metering_data']) collector = messaging.get_rpc_server( self.transport, self.CONF.publisher_rpc.metering_topic, endpoint) endpoint.record_metering_data.side_effect = (lambda *args, **kwds: collector.stop()) collector.start() eventlet.sleep() publisher.publish_samples(context.RequestContext(), self.test_sample_data) collector.wait() class Matcher(object): @staticmethod def __eq__(data): for i, sample_item in enumerate(data): if (sample_item['counter_name'] != self.test_sample_data[i].name): return False return True endpoint.record_metering_data.assert_called_once_with( mock.ANY, data=Matcher())
def connect(self): url = cfg.CONF.database.connection if not url: LOG.error('Can not get the address of the sourcedatabase, please set up in the qyceilometer.conf') raise connection_options = pymongo.uri_parser.parse_uri(url) del connection_options['database'] del connection_options['username'] del connection_options['password'] del connection_options['collection'] pool_key = tuple(connection_options) if pool_key in self._pool: client = self._pool.get(pool_key)() if client: return client splitted_url = netutils.urlsplit(url) log_data = {'db': splitted_url.scheme, 'nodelist': connection_options['nodelist']} LOG.info(('Connecting to %(db)s on %(nodelist)s') % log_data) client = self._mongo_connect(url) LOG.info(('Connectted to %(db)s on %(nodelist)s') % log_data) self._pool[pool_key] = weakref.ref(client) connection_options = pymongo.uri_parser.parse_uri(url) db = getattr(client, connection_options['database']) return db
def test_published_concurrency(self): """Test concurrent access to the local queue of the rpc publisher.""" publisher = self.publisher_cls( netutils.urlsplit('%s://' % self.protocol)) with mock.patch.object(publisher, '_send') as fake_send: def fake_send_wait(ctxt, topic, meters): fake_send.side_effect = mock.Mock() # Sleep to simulate concurrency and allow other threads to work eventlet.sleep(0) fake_send.side_effect = fake_send_wait job1 = eventlet.spawn(getattr(publisher, self.pub_func), mock.MagicMock(), self.test_data) job2 = eventlet.spawn(getattr(publisher, self.pub_func), mock.MagicMock(), self.test_data) job1.wait() job2.wait() self.assertEqual('default', publisher.policy) self.assertEqual(2, len(fake_send.mock_calls)) self.assertEqual(0, len(publisher.local_queue))
def check_alarm_actions(alarm): max_actions = pecan.request.cfg.api.alarm_max_actions for state in state_kind: actions_name = state.replace(" ", "_") + "_actions" actions = getattr(alarm, actions_name) if not actions: continue action_set = set(actions) if len(actions) != len(action_set): LOG.info(_LI("duplicate actions are found: %s, " "remove duplicate ones"), actions) actions = list(action_set) setattr(alarm, actions_name, actions) if 0 < max_actions < len(actions): error = _("%(name)s count exceeds maximum value " "%(maximum)d") % { "name": actions_name, "maximum": max_actions, } raise base.ClientSideError(error) limited = rbac.get_limited_to_project(pecan.request.headers, pecan.request.enforcer) for action in actions: try: url = netutils.urlsplit(action) except Exception: error = _("Unable to parse action %s") % action raise base.ClientSideError(error) if url.scheme not in ACTIONS_SCHEMA: error = _("Unsupported action %s") % action raise base.ClientSideError(error) if limited and url.scheme in ("log", "test"): error = _("You are not authorized to create " "action: %s") % action raise base.ClientSideError(error, status_code=401)
def authenticate(self): magic_tuple = netutils.urlsplit(self.auth_url) scheme, netloc, path, query, frag = magic_tuple port = magic_tuple.port if port is None: port = 80 path_parts = path.split('/') for part in path_parts: if len(part) > 0 and part[0] == 'v': self.version = part break if self.auth_token and self.management_url: self._save_keys() return # TODO(sandy): Assume admin endpoint is 35357 for now. # Ideally this is going to have to be provided by the service catalog. new_netloc = netloc.replace(':%d' % port, ':%d' % (35357,)) admin_url = parse.urlunsplit( (scheme, new_netloc, path, query, frag)) auth_url = self.auth_url if self.version == "v2.0": # FIXME(chris): This should be better. while auth_url: if not self.auth_system or self.auth_system == 'keystone': auth_url = self._v2_auth(auth_url) else: auth_url = self._plugin_auth(auth_url) # Are we acting on behalf of another user via an # existing token? If so, our actual endpoints may # be different than that of the admin token. if self.proxy_token: if self.bypass_url: self.set_management_url(self.bypass_url) else: self._fetch_endpoints_from_auth(admin_url) # Since keystone no longer returns the user token # with the endpoints any more, we need to replace # our service account token with the user token. self.auth_token = self.proxy_token else: try: while auth_url: auth_url = self._v1_auth(auth_url) # In some configurations nova makes redirection to # v2.0 keystone endpoint. Also, new location does not contain # real endpoint, only hostname and port. except exceptions.AuthorizationFailure: if auth_url.find('v2.0') < 0: auth_url = auth_url + '/v2.0' self._v2_auth(auth_url) if self.bypass_url: self.set_management_url(self.bypass_url) elif not self.management_url: raise exceptions.Unauthorized('Nova Client') self._save_keys()
def delete_actions(self): auth_plugin = pecan.request.environ.get('keystone.token_auth') for action in itertools.chain(self.ok_actions, self.alarm_actions, self.insufficient_data_actions): url = netutils.urlsplit(action) if self._is_trust_url(url) and url.password: keystone_client.delete_trust_id(url.username, auth_plugin)
def _handle_action(self, action, alarm_id, alarm_name, severity, previous, current, reason, reason_data): try: action = netutils.urlsplit(action) except Exception: LOG.error( _("Unable to parse action %(action)s for alarm %(alarm_id)s"), {'action': action, 'alarm_id': alarm_id}) return try: notifier = self.notifiers[action.scheme].obj except KeyError: scheme = action.scheme LOG.error( _("Action %(scheme)s for alarm %(alarm_id)s is unknown, " "cannot notify"), {'scheme': scheme, 'alarm_id': alarm_id}) return try: LOG.debug("Notifying alarm %(id)s with action %(act)s", {'id': alarm_id, 'act': action}) notifier.notify(action, alarm_id, alarm_name, severity, previous, current, reason, reason_data) except Exception: LOG.exception(_("Unable to notify alarm %s"), alarm_id) return
def update_actions(self, old_alarm=None): trustor_user_id = pecan.request.headers.get("X-User-Id") trustor_project_id = pecan.request.headers.get("X-Project-Id") roles = pecan.request.headers.get("X-Roles", "") if roles: roles = roles.split(",") else: roles = [] auth_plugin = pecan.request.environ.get("keystone.token_auth") for actions in (self.ok_actions, self.alarm_actions, self.insufficient_data_actions): if actions is not None: for index, action in enumerate(actions[:]): url = netutils.urlsplit(action) if self._is_trust_url(url): if "@" not in url.netloc: # We have a trust action without a trust ID, # create it trust_id = keystone_client.create_trust_id( pecan.request.cfg, trustor_user_id, trustor_project_id, roles, auth_plugin ) netloc = "%s:delete@%s" % (trust_id, url.netloc) url = list(url) url[1] = netloc actions[index] = urlparse.urlunsplit(url) if old_alarm: new_actions = list( itertools.chain(self.ok_actions or [], self.alarm_actions or [], self.insufficient_data_actions or []) ) for action in itertools.chain( old_alarm.ok_actions or [], old_alarm.alarm_actions or [], old_alarm.insufficient_data_actions or [] ): if action not in new_actions: self.delete_trust(action)
def test_published(self): self.data_sent = [] with mock.patch("socket.socket", self._make_fake_socket(self.data_sent)): publisher = udp.UDPPublisher(self.CONF, netutils.urlsplit("udp://somehost")) publisher.publish_samples(self.test_data) self.assertEqual(5, len(self.data_sent)) sent_counters = [] for data, dest in self.data_sent: counter = msgpack.loads(data, encoding="utf-8") sent_counters.append(counter) # Check destination self.assertEqual(("somehost", self.CONF.collector.udp_port), dest) # Check that counters are equal def sort_func(counter): return counter["counter_name"] counters = [utils.meter_message_from_counter(d, "not-so-secret") for d in self.test_data] counters.sort(key=sort_func) sent_counters.sort(key=sort_func) self.assertEqual(counters, sent_counters)
def setUp(self): super(TestSNMPInspector, self).setUp() self.inspector = snmp.SNMPInspector() self.host = netutils.urlsplit("snmp://localhost") self.useFixture(mockpatch.PatchObject( snmp.cmdgen, 'CommandGenerator', return_value=FakeCommandGenerator()))
def test_publish_error(self): with mock.patch('socket.socket', self._make_broken_socket): publisher = udp.UDPPublisher( netutils.urlsplit('udp://localhost')) publisher.publish_samples(None, self.test_data)
def connect(self, url, max_retries, retry_interval): connection_options = pymongo.uri_parser.parse_uri(url) del connection_options['database'] del connection_options['username'] del connection_options['password'] del connection_options['collection'] pool_key = tuple(connection_options) if pool_key in self._pool: client = self._pool.get(pool_key)() if client: return client splitted_url = netutils.urlsplit(url) log_data = {'db': splitted_url.scheme, 'nodelist': connection_options['nodelist']} LOG.info('Connecting to %(db)s on %(nodelist)s' % log_data) try: client = MongoProxy(pymongo.MongoClient(url), max_retries, retry_interval) except pymongo.errors.ConnectionFailure as e: LOG.warning(_('Unable to connect to the database server: ' '%(errmsg)s.') % {'errmsg': e}) raise self._pool[pool_key] = weakref.ref(client) return client
def get_coordinator(backend_url, member_id, **kwargs): """Initialize and load the backend. :param backend_url: the backend URL to use :type backend: str :param member_id: the id of the member :type member_id: str :param kwargs: additional coordinator options (these take precedence over options of the **same** name found in the ``backend_url`` arguments query string) """ parsed_url = netutils.urlsplit(backend_url) parsed_qs = six.moves.urllib.parse.parse_qs(parsed_url.query) if kwargs: options = {} for (k, v) in six.iteritems(kwargs): options[k] = [v] for (k, v) in six.iteritems(parsed_qs): if k not in options: options[k] = v else: options = parsed_qs return driver.DriverManager( namespace=TOOZ_BACKENDS_NAMESPACE, name=parsed_url.scheme, invoke_on_load=True, invoke_args=(member_id, parsed_url, options)).driver
def test_file_publisher_json(self): tempdir = tempfile.mkdtemp() name = '%s/log_file_json' % tempdir parsed_url = netutils.urlsplit('file://%s?json' % name) publisher = file.FilePublisher(self.CONF, parsed_url) publisher.publish_samples(self.test_data) handler = publisher.publisher_logger.handlers[0] self.assertIsInstance(handler, logging.handlers.RotatingFileHandler) self.assertEqual([0, name, 0], [handler.maxBytes, handler.baseFilename, handler.backupCount]) self.assertTrue(os.path.exists(name)) with open(name, 'r') as f: content = f.readlines() self.assertEqual(len(self.test_data), len(content)) for index, line in enumerate(content): try: json_data = json.loads(line) except ValueError: self.fail("File written is not valid json") self.assertEqual(self.test_data[index].id, json_data['id']) self.assertEqual(self.test_data[index].timestamp, json_data['timestamp'])
def test_published_with_per_meter_topic(self): publisher = msg_publisher.RPCPublisher( netutils.urlsplit('rpc://?per_meter_topic=1')) with mock.patch.object(publisher.rpc_client, 'prepare') as prepare: publisher.publish_samples(mock.MagicMock(), self.test_sample_data) class MeterGroupMatcher(object): def __eq__(self, meters): return len(set(meter['counter_name'] for meter in meters)) == 1 topic = self.CONF.publisher_rpc.metering_topic expected = [mock.call(topic=topic), mock.call().cast(mock.ANY, 'record_metering_data', data=mock.ANY), mock.call(topic=topic + '.test'), mock.call().cast(mock.ANY, 'record_metering_data', data=MeterGroupMatcher()), mock.call(topic=topic + '.test2'), mock.call().cast(mock.ANY, 'record_metering_data', data=MeterGroupMatcher()), mock.call(topic=topic + '.test3'), mock.call().cast(mock.ANY, 'record_metering_data', data=MeterGroupMatcher())] self.assertEqual(expected, prepare.mock_calls)
def test_published_with_policy_queue_and_rpc_down(self): publisher = self.publisher_cls( self.CONF, netutils.urlsplit('%s://?policy=queue' % self.protocol)) side_effect = msg_publisher.DeliveryFailure() with mock.patch.object(publisher, '_send') as fake_send: fake_send.side_effect = side_effect getattr(publisher, self.pub_func)(self.test_data) self.assertEqual(1, len(publisher.local_queue)) fake_send.assert_called_once_with( self.topic, mock.ANY)
def get_publisher(conf, url, namespace): """Get publisher driver and load it. :param URL: URL for the publisher :param namespace: Namespace to use to look for drivers. """ parse_result = netutils.urlsplit(url) loaded_driver = driver.DriverManager(namespace, parse_result.scheme) if issubclass(loaded_driver.driver, ConfigPublisherBase): return loaded_driver.driver(conf, parse_result) else: return loaded_driver.driver(parse_result)
def _parse_my_resource(resource): parse_url = netutils.urlsplit(resource) params = urlparse.parse_qs(parse_url.query) parts = urlparse.ParseResult(parse_url.scheme, parse_url.netloc, parse_url.path, None, None, None) return parts, params
def _do_test_activity_filter(self, expected_measures, fake_batch): url = netutils.urlsplit("gnocchi://") d = gnocchi.GnocchiPublisher(self.conf.conf, url) d._already_checked_archive_policies = True d.publish_samples(self.samples) self.assertEqual(1, len(fake_batch.mock_calls)) measures = fake_batch.mock_calls[0][1][0] self.assertEqual( expected_measures, sum( len(m["measures"]) for rid in measures for m in measures[rid].values()))
def test_publish_to_host_with_default_policy(self): publisher = kafka.KafkaBrokerPublisher( self.CONF, netutils.urlsplit( 'kafka://127.0.0.1:9092?topic=ceilometer&policy=default')) with mock.patch.object(publisher, '_producer') as fake_producer: fake_producer.send.side_effect = TypeError self.assertRaises(msg_publisher.DeliveryFailure, publisher.publish_samples, self.test_data) self.assertEqual(100, len(fake_producer.send.mock_calls)) self.assertEqual(0, len(publisher.local_queue))
def setUp(self): super(TestSNMPInspector, self).setUp() self.inspector = snmp.SNMPInspector() self.host = netutils.urlsplit("snmp://localhost") self.useFixture( mockpatch.PatchObject(self.inspector._cmdGen, 'getCmd', new=faux_getCmd_new)) self.useFixture( mockpatch.PatchObject(self.inspector._cmdGen, 'bulkCmd', new=faux_bulkCmd_new))
def test_published_with_policy_block(self, mylog): publisher = self.publisher_cls( netutils.urlsplit('%s://?policy=default' % self.protocol)) side_effect = msg_publisher.DeliveryFailure() with mock.patch.object(publisher, '_send') as fake_send: fake_send.side_effect = side_effect self.assertRaises(msg_publisher.DeliveryFailure, getattr(publisher, self.pub_func), mock.MagicMock(), self.test_data) self.assertTrue(mylog.info.called) self.assertEqual(0, len(publisher.local_queue)) fake_send.assert_called_once_with(mock.ANY, self.topic, mock.ANY)
def parse_driver_info(node): """Parse the information required for Ironic to connect to iBMC. :param node: an Ironic node object :returns: dictionary of parameters :raises: InvalidParameterValue on malformed parameter(s) :raises: MissingParameterValue on missing parameter(s) """ driver_info = node.driver_info or {} missing_info = [key for key in REQUIRED_PROPERTIES if not driver_info.get(key)] if missing_info: raise exception.MissingParameterValue(_( 'Missing the following iBMC properties in node ' '%(node)s driver_info: %(info)s') % {'node': node.uuid, 'info': missing_info}) # Validate the iBMC address address = driver_info['ibmc_address'] if '://' not in address: address = 'https://%s' % address parsed = netutils.urlsplit(address) if not parsed.netloc: raise exception.InvalidParameterValue( _('Invalid iBMC address %(address)s set in ' 'driver_info/ibmc_address on node %(node)s') % {'address': address, 'node': node.uuid}) # Check if verify_ca is a Boolean or a file/directory in the file-system verify_ca = driver_info.get('ibmc_verify_ca', True) if isinstance(verify_ca, str): if not os.path.exists(verify_ca): try: verify_ca = strutils.bool_from_string(verify_ca, strict=True) except ValueError: raise exception.InvalidParameterValue( _('Invalid value type set in driver_info/' 'ibmc_verify_ca on node %(node)s. ' 'The value should be a Boolean or the path ' 'to a file/directory, not "%(value)s"' ) % {'value': verify_ca, 'node': node.uuid}) elif not isinstance(verify_ca, bool): raise exception.InvalidParameterValue( _('Invalid value type set in driver_info/ibmc_verify_ca ' 'on node %(node)s. The value should be a Boolean or the path ' 'to a file/directory, not "%(value)s"') % {'value': verify_ca, 'node': node.uuid}) return {'address': address, 'username': driver_info.get('ibmc_username'), 'password': driver_info.get('ibmc_password'), 'verify_ca': verify_ca}
def delete_cluster(self, context, cluster): LOG.info("Starting to delete cluster %s", cluster.uuid) self.pre_delete_cluster(context, cluster) c_template = conductor_utils.retrieve_cluster_template( context, cluster ) # NOTE: The fake fields are only for the yaml file integrity and do not # affect the deletion params = { "namespace": cluster.uuid, "cloud_provider_tag": "fake", "kube_version": "fake", } _delete_manifest = functools.partial(self._delete_manifest, params) LOG.info("Deleting components for cluster %s", cluster.uuid) for tmpl in [ "openstack-cloud-controller-manager.yaml.j2", "kube-scheduler.yaml.j2", "kube-controllermgr.yaml.j2", "kube-apiserver.yaml.j2", "etcd.yaml.j2", "secrets.yaml.j2", "namespace.yaml.j2" ]: _delete_manifest(tmpl) # Delete floating ip if needed. if (self._master_lb_fip_enabled(cluster, c_template) and cluster.api_address): network_client = clients.OpenStackClients(context).neutron() ip = netutils.urlsplit(cluster.api_address).netloc.split(":")[0] fips = network_client.list_floatingips(floating_ip_address=ip) for fip in fips['floatingips']: LOG.info("Deleting floating ip %s for cluster %s", fip["floating_ip_address"], cluster.uuid) network_client.delete_floatingip(fip['id']) # Delete VIP port LOG.info("Deleting ports for cluster %s", cluster.uuid) tag = {"magnum": cluster.uuid} tags = [jsonutils.dumps(tag)] neutron.delete_port_by_tags(context, tags) # Delete Heat stack. if cluster.stack_id: LOG.info("Deleting Heat stack %s for cluster %s", cluster.stack_id, cluster.uuid) self._delete_stack( context, clients.OpenStackClients(context), cluster )
def test_direct_publisher(self): """Test samples are saved.""" self.CONF.set_override('connection', self.db_manager.url, group='database') parsed_url = netutils.urlsplit('direct://') publisher = direct.DirectPublisher(parsed_url) publisher.publish_samples(self.test_data) meters = list(self.conn.get_meters(resource=self.resource_id)) names = sorted([meter.name for meter in meters]) self.assertEqual(3, len(meters), 'There should be 3 samples') self.assertEqual(['alpha', 'beta', 'gamma'], names)
def test_published_with_policy_incorrect(self, mylog): publisher = self.publisher_cls( netutils.urlsplit('%s://?policy=notexist' % self.protocol)) side_effect = oslo.messaging.MessageDeliveryFailure() with mock.patch.object(publisher, '_send') as fake_send: fake_send.side_effect = side_effect self.assertRaises(oslo.messaging.MessageDeliveryFailure, getattr(publisher, self.pub_func), mock.MagicMock(), self.test_data) self.assertTrue(mylog.warn.called) self.assertEqual('default', publisher.policy) self.assertEqual(0, len(publisher.local_queue)) fake_send.assert_called_once_with(mock.ANY, self.topic, mock.ANY)
def test_published_with_policy_block(self, mylog): publisher = self.publisher_cls( netutils.urlsplit('%s://?policy=default' % self.protocol)) side_effect = oslo.messaging.MessageDeliveryFailure() with mock.patch.object(publisher, '_send') as fake_send: fake_send.side_effect = side_effect self.assertRaises(oslo.messaging.MessageDeliveryFailure, publisher.publish_samples, mock.MagicMock(), self.test_data) self.assertTrue(mylog.info.called) self.assertEqual(0, len(publisher.local_queue)) fake_send.assert_called_once_with( mock.ANY, self.CONF.publisher_rpc.metering_topic, mock.ANY)
def test_publish_target(self): publisher = msg_publisher.RPCPublisher( netutils.urlsplit('rpc://?target=custom_procedure_call')) cast_context = mock.MagicMock() with mock.patch.object(publisher.rpc_client, 'prepare') as prepare: prepare.return_value = cast_context publisher.publish_samples(mock.MagicMock(), self.test_sample_data) prepare.assert_called_once_with( topic=self.CONF.publisher_rpc.metering_topic) cast_context.cast.assert_called_once_with( mock.ANY, 'custom_procedure_call', data=mock.ANY)
def test_publish_event_with_default_policy(self): publisher = kafka.KafkaBrokerPublisher( netutils.urlsplit('kafka://127.0.0.1:9092?topic=ceilometer')) with mock.patch.object(publisher, '_producer') as fake_producer: publisher.publish_events(self.test_event_data) self.assertEqual(5, len(fake_producer.send_messages.mock_calls)) with mock.patch.object(publisher, '_producer') as fake_producer: fake_producer.send_messages.side_effect = Exception("test") self.assertRaises(msg_publisher.DeliveryFailure, publisher.publish_events, self.test_event_data) self.assertEqual(100, len(fake_producer.send_messages.mock_calls)) self.assertEqual(0, len(publisher.local_queue))
def test_published_with_no_policy(self, mylog): publisher = self.publisher_cls( self.CONF, netutils.urlsplit('%s://' % self.protocol)) side_effect = msg_publisher.DeliveryFailure() with mock.patch.object(publisher, '_send') as fake_send: fake_send.side_effect = side_effect self.assertRaises(msg_publisher.DeliveryFailure, getattr(publisher, self.pub_func), self.test_data) self.assertTrue(mylog.info.called) self.assertEqual('default', publisher.policy) self.assertEqual(0, len(publisher.local_queue)) self.assertEqual(100, len(fake_send.mock_calls)) fake_send.assert_called_with(self.topic, mock.ANY)
def test_publish_event_with_default_policy(self, mock_method): publisher = KafkaBrokerPublisher( netutils.urlsplit('kafka://127.0.0.1:9092?topic=ceilometer')) with mock.patch.object(KafkaBrokerPublisher, '_send') as fake_send: publisher.publish_events(mock.MagicMock(), self.test_event_data) self.assertEqual(1, len(fake_send.mock_calls)) with mock.patch.object(KafkaBrokerPublisher, '_send') as fake_send: fake_send.side_effect = TypeError self.assertRaises(TypeError, publisher.publish_events, mock.MagicMock(), self.test_event_data) self.assertEqual(100, len(fake_send.mock_calls)) self.assertEqual(0, len(publisher.local_queue))
def test_publish_to_down_host_with_default_queue_size(self, mock_method): publisher = KafkaBrokerPublisher( netutils.urlsplit( 'kafka://127.0.0.1:9092?topic=ceilometer&policy=queue')) for i in range(0, 2000): for s in self.test_data: s.name = 'test-%d' % i publisher.publish_samples(mock.MagicMock(), self.test_data) self.assertEqual(1024, len(publisher.local_queue)) self.assertEqual('test-976', publisher.local_queue[0][0]['counter_name']) self.assertEqual('test-1999', publisher.local_queue[1023][0]['counter_name'])
def test_published_with_policy_default_sized_queue_and_rpc_down(self): publisher = self.publisher_cls( self.CONF, netutils.urlsplit('%s://?policy=queue' % self.protocol)) side_effect = msg_publisher.DeliveryFailure() with mock.patch.object(publisher, '_send') as fake_send: fake_send.side_effect = side_effect for i in range(0, 2000): for s in self.test_data: setattr(s, self.attr, 'test-%d' % i) getattr(publisher, self.pub_func)(self.test_data) self.assertEqual(1024, len(publisher.local_queue)) self.assertEqual('test-976', publisher.local_queue[0][1][0][self.attr]) self.assertEqual('test-1999', publisher.local_queue[1023][1][0][self.attr])
def test_file_publisher_maxbytes(self): # Test valid configurations tempdir = tempfile.mkdtemp() name = '%s/log_file' % tempdir parsed_url = netutils.urlsplit( 'file://%s?max_bytes=50&backup_count=3' % name) publisher = file.FilePublisher(self.CONF, parsed_url) publisher.publish_samples(self.test_data) handler = publisher.publisher_logger.handlers[0] self.assertIsInstance(handler, logging.handlers.RotatingFileHandler) self.assertEqual( [50, name, 3], [handler.maxBytes, handler.baseFilename, handler.backupCount]) # The rotating file gets created since only allow 50 bytes. self.assertTrue(os.path.exists('%s.1' % name))
def test_published_with_policy_default_sized_queue_and_rpc_down(self): publisher = self.publisher_cls( netutils.urlsplit('%s://?policy=queue' % self.protocol)) side_effect = oslo.messaging.MessageDeliveryFailure() with mock.patch.object(publisher, '_send') as fake_send: fake_send.side_effect = side_effect for i in range(0, 2000): for s in self.test_data: s.source = 'test-%d' % i publisher.publish_samples(mock.MagicMock(), self.test_data) self.assertEqual(1024, len(publisher.local_queue)) self.assertEqual('test-976', publisher.local_queue[0][2][0]['source']) self.assertEqual('test-1999', publisher.local_queue[1023][2][0]['source'])
def update_actions(self, old_alarm=None): trustor_user_id = pecan.request.headers.get('X-User-Id') trustor_project_id = pecan.request.headers.get('X-Project-Id') roles = pecan.request.headers.get('X-Roles', '') if roles: roles = roles.split(',') else: roles = [] auth_plugin = pecan.request.environ.get('keystone.token_auth') if old_alarm: prev_trust_ids = set(old_alarm._get_existing_trust_ids()) else: prev_trust_ids = set() trust_id = prev_trust_ids.pop() if prev_trust_ids else None trust_id_used = False for actions in (self.ok_actions, self.alarm_actions, self.insufficient_data_actions): if actions is not None: for index, action in enumerate(actions[:]): url = netutils.urlsplit(action) if self._is_trust_url(url): if '@' in url.netloc: errmsg = _("trust URL cannot contain a trust ID.") raise base.ClientSideError(errmsg) if trust_id is None: # We have a trust action without a trust ID, # create it trust_id = keystone_client.create_trust_id( pecan.request.cfg, trustor_user_id, trustor_project_id, roles, auth_plugin) if trust_id_used: pw = '' else: pw = ':delete' trust_id_used = True netloc = '%s%s@%s' % (trust_id, pw, url.netloc) url = urlparse.SplitResult(url.scheme, netloc, url.path, url.query, url.fragment) actions[index] = url.geturl() if trust_id is not None and not trust_id_used: prev_trust_ids.add(trust_id) for old_trust_id in prev_trust_ids: keystone_client.delete_trust_id(pecan.request.cfg, old_trust_id, auth_plugin)
def _handle_action(notifiers, action, alarm_id, alarm_name, severity, previous, current, reason, reason_data): """Process action on alarm :param notifiers: list of possible notifiers. :param action: The action that is being attended, as a parsed URL. :param alarm_id: The triggered alarm. :param alarm_name: The name of triggered alarm. :param severity: The level of triggered alarm :param previous: The previous state of the alarm. :param current: The current state of the alarm. :param reason: The reason the alarm changed its state. :param reason_data: A dict representation of the reason. """ try: action = netutils.urlsplit(action) except Exception: LOG.error( _("Unable to parse action %(action)s for alarm %(alarm_id)s"), { 'action': action, 'alarm_id': alarm_id }) return try: notifier = notifiers[action.scheme].obj except KeyError: scheme = action.scheme LOG.error( _("Action %(scheme)s for alarm %(alarm_id)s is unknown, " "cannot notify"), { 'scheme': scheme, 'alarm_id': alarm_id }) return try: LOG.debug("Notifying alarm %(id)s with action %(act)s", { 'id': alarm_id, 'act': action }) notifier.notify(action, alarm_id, alarm_name, severity, previous, current, reason, reason_data) except Exception: LOG.exception(_("Unable to notify alarm %s"), alarm_id) return
def _get_kubeconfig(self, context, cluster, ca_cert_encoded=None): """Prepare kubeconfig file to interact with the new cluster.""" # TODO(lxkong): This kubeconfig file should be stored in a shared place # between magnum controllers. cluster_cache_dir = os.path.join( CONF.cluster.temp_cache_dir, cluster.uuid ) fileutils.ensure_tree(cluster_cache_dir) kubeconfig_path = os.path.join(cluster_cache_dir, "kubeconfig") if os.path.exists(kubeconfig_path): return kubeconfig_path if ca_cert_encoded is None: ca_cert = cert_manager.get_cluster_ca_certificate( cluster, context=context ) ca_cert_encoded = base64.b64encode(ca_cert.get_certificate()) admin_cert = cert_manager.get_cluster_magnum_cert( cluster, context=context ) admin_cert_encoded = base64.b64encode(admin_cert.get_certificate()) admin_key_encoded = base64.b64encode( admin_cert.get_decrypted_private_key()) split_ret = netutils.urlsplit(cluster.api_address) external_apiserver_address = split_ret.netloc.split(":")[0] kubeconfig_params = { "cluster_id": cluster.uuid, "apiserver_address": external_apiserver_address, "ca_cert": ca_cert_encoded, "cert": admin_cert_encoded, "key": admin_key_encoded, "user": "******", } kubeconfig_template = self.jinja_env.get_template("kubeconfig.j2") kubeconfig = kubeconfig_template.render(kubeconfig_params) with open(kubeconfig_path, 'w') as fd: fd.write(kubeconfig) return kubeconfig_path
def test_publish_to_unreachable_host_with_default_queue_size(self): publisher = kafka_publisher.KafkaBrokerPublisher( netutils.urlsplit( 'kafka://127.0.0.1:9092?topic=ceilometer&policy=queue')) with mock.patch.object(publisher, '_get_client') as fake_client: fake_client.return_value = None for i in range(0, 2000): for s in self.test_data: s.name = 'test-%d' % i publisher.publish_samples(mock.MagicMock(), self.test_data) self.assertEqual(1024, len(publisher.local_queue)) self.assertEqual('test-976', publisher.local_queue[0][0]['counter_name']) self.assertEqual('test-1999', publisher.local_queue[1023][0]['counter_name'])
def get_coordinator(backend_url, member_id, characteristics=frozenset(), **kwargs): """Initialize and load the backend. :param backend_url: the backend URL to use :type backend: str :param member_id: the id of the member :type member_id: str :param characteristics: set :type characteristics: set of :py:class:`.Characteristics` that will be matched to the requested driver (this **will** become a **required** parameter in a future tooz version) :param kwargs: additional coordinator options (these take precedence over options of the **same** name found in the ``backend_url`` arguments query string) """ parsed_url = netutils.urlsplit(backend_url) parsed_qs = six.moves.urllib.parse.parse_qs(parsed_url.query) if kwargs: options = {} for (k, v) in six.iteritems(kwargs): options[k] = [v] for (k, v) in six.iteritems(parsed_qs): if k not in options: options[k] = v else: options = parsed_qs d = driver.DriverManager(namespace=TOOZ_BACKENDS_NAMESPACE, name=parsed_url.scheme, invoke_on_load=True, invoke_args=(member_id, parsed_url, options)).driver characteristics = set(characteristics) driver_characteristics = set(getattr(d, 'CHARACTERISTICS', set())) missing_characteristics = characteristics - driver_characteristics if missing_characteristics: raise ToozDriverChosenPoorly( "Desired characteristics %s" " is not a strict subset of driver" " characteristics %s, %s" " characteristics were not found" % (characteristics, driver_characteristics, missing_characteristics)) return d
def test_published_with_policy_sized_queue_and_rpc_down(self): publisher = self.publisher_cls( netutils.urlsplit('%s://?policy=queue&max_queue_length=3' % self.protocol)) side_effect = msg_publisher.DeliveryFailure() with mock.patch.object(publisher, '_send') as fake_send: fake_send.side_effect = side_effect for i in range(0, 5): for s in self.test_data: setattr(s, self.attr, 'test-%d' % i) getattr(publisher, self.pub_func)(self.test_data) self.assertEqual(3, len(publisher.local_queue)) self.assertEqual('test-2', publisher.local_queue[0][1][0][self.attr]) self.assertEqual('test-3', publisher.local_queue[1][1][0][self.attr]) self.assertEqual('test-4', publisher.local_queue[2][1][0][self.attr])
def test_unhandled_meter(self, fake_batch): samples = [ sample.Sample(name='unknown.meter', unit='GB', type=sample.TYPE_GAUGE, volume=2, user_id='test_user', project_id='test_project', source='openstack', timestamp='2014-05-08 20:23:48.028195', resource_id='randomid', resource_metadata={}) ] url = netutils.urlsplit("gnocchi://") d = gnocchi.GnocchiPublisher(self.conf.conf, url) d.publish_samples(samples) self.assertEqual(0, len(fake_batch.call_args[0][1]))
def test_file_publisher_csv(self): # Test configurations with format=csv tempdir = tempfile.mkdtemp() name = '%s/log_file' % tempdir parsed_url = netutils.urlsplit( 'file://%s?max_bytes=50&backup_count=3&format=csv' % name) publisher = file.FilePublisher(self.CONF, parsed_url) publisher.publish_samples(self.test_data) self.assertTrue(os.path.exists('%s' % name)) csv_fileh = open(name, 'rb') try: dialect = csv.Sniffer().sniff(csv_fileh.read(1024).decode()) self.assertIsNotNone(dialect) csv_fileh.seek(0) except csv.Error as e: self.assertRaises(csv.Error, e)
def test_publish_to_down_host_with_default_queue_size(self): publisher = kafka.KafkaBrokerPublisher(self.CONF, netutils.urlsplit( 'kafka://127.0.0.1:9092?topic=ceilometer&policy=queue')) with mock.patch.object(publisher, '_producer') as fake_producer: fake_producer.send.side_effect = Exception("test") for i in range(0, 2000): for s in self.test_data: s.name = 'test-%d' % i publisher.publish_samples(self.test_data) self.assertEqual(1024, len(publisher.local_queue)) self.assertEqual('test-976', publisher.local_queue[0][1][0]['counter_name']) self.assertEqual('test-1999', publisher.local_queue[1023][1][0]['counter_name'])
def check_alarm_actions(alarm): actions_schema = ceilometer_alarm.NOTIFIER_SCHEMAS for state in state_kind: actions_name = state.replace(" ", "_") + '_actions' actions = getattr(alarm, actions_name) if not actions: continue for action in actions: try: url = netutils.urlsplit(action) except Exception: error = _("Unable to parse action %s") % action raise base.ClientSideError(error) if url.scheme not in actions_schema: error = _("Unsupported action %s") % action raise base.ClientSideError(error)