Merge "Use keystoneauth1 instead of manual setup"
This commit is contained in:
commit
e1364ecf2d
@ -63,7 +63,7 @@ class AlarmGnocchiThresholdRule(base.AlarmRule):
|
||||
ks_client = keystone_client.get_client(pecan.request.cfg)
|
||||
gnocchi_url = pecan.request.cfg.gnocchi_url
|
||||
headers = {'Content-Type': "application/json",
|
||||
'X-Auth-Token': ks_client.auth_token}
|
||||
'X-Auth-Token': keystone_client.get_auth_token(ks_client)}
|
||||
try:
|
||||
r = requests.get("%s/v1/capabilities" % gnocchi_url,
|
||||
headers=headers)
|
||||
@ -103,7 +103,7 @@ class MetricOfResourceRule(AlarmGnocchiThresholdRule):
|
||||
ks_client = keystone_client.get_client(pecan.request.cfg)
|
||||
gnocchi_url = pecan.request.cfg.gnocchi_url
|
||||
headers = {'Content-Type': "application/json",
|
||||
'X-Auth-Token': ks_client.auth_token}
|
||||
'X-Auth-Token': keystone_client.get_auth_token(ks_client)}
|
||||
try:
|
||||
r = requests.get("%s/v1/resource/%s/%s" % (
|
||||
gnocchi_url, rule.resource_type,
|
||||
@ -168,7 +168,8 @@ class AggregationMetricByResourcesLookupRule(AlarmGnocchiThresholdRule):
|
||||
rule.resource_type,
|
||||
rule.metric),
|
||||
'headers': {'Content-Type': "application/json",
|
||||
'X-Auth-Token': ks_client.auth_token},
|
||||
'X-Auth-Token': keystone_client.get_auth_token(
|
||||
ks_client)},
|
||||
'params': {'aggregation': rule.aggregation_method,
|
||||
'needed_overlap': 0},
|
||||
'data': rule.query,
|
||||
|
@ -20,6 +20,7 @@ import requests
|
||||
|
||||
from aodh.evaluator import threshold
|
||||
from aodh.i18n import _
|
||||
from aodh import keystone_client
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
@ -40,7 +41,7 @@ class GnocchiThresholdEvaluator(threshold.ThresholdEvaluator):
|
||||
def _get_headers(self, content_type="application/json"):
|
||||
return {
|
||||
'Content-Type': content_type,
|
||||
'X-Auth-Token': self.ks_client.auth_token,
|
||||
'X-Auth-Token': keystone_client.get_auth_token(self.ks_client),
|
||||
}
|
||||
|
||||
def _statistics(self, alarm, start, end):
|
||||
|
@ -25,6 +25,7 @@ from oslo_utils import timeutils
|
||||
from aodh import evaluator
|
||||
from aodh.evaluator import utils
|
||||
from aodh.i18n import _, _LW
|
||||
from aodh import keystone_client
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
@ -53,20 +54,13 @@ class ThresholdEvaluator(evaluator.Evaluator):
|
||||
if self._cm_client is None:
|
||||
auth_config = self.conf.service_credentials
|
||||
self._cm_client = ceiloclient.get_client(
|
||||
2,
|
||||
os_auth_url=auth_config.os_auth_url.replace('/v2.0', '/'),
|
||||
os_region_name=auth_config.os_region_name,
|
||||
os_tenant_name=auth_config.os_tenant_name,
|
||||
os_password=auth_config.os_password,
|
||||
os_username=auth_config.os_username,
|
||||
os_cacert=auth_config.os_cacert,
|
||||
os_endpoint_type=auth_config.os_endpoint_type,
|
||||
insecure=auth_config.insecure,
|
||||
timeout=self.conf.http_timeout,
|
||||
os_user_domain_id=auth_config.os_user_domain_id,
|
||||
os_project_name=auth_config.os_project_name,
|
||||
os_project_domain_id=auth_config.os_project_domain_id,
|
||||
version=2,
|
||||
session=keystone_client.get_session(self.conf),
|
||||
# ceiloclient adapter options
|
||||
region_name=auth_config.region_name,
|
||||
interface=auth_config.interface,
|
||||
)
|
||||
|
||||
return self._cm_client
|
||||
|
||||
@classmethod
|
||||
|
@ -13,64 +13,60 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import os
|
||||
|
||||
from keystoneclient import discover as ks_discover
|
||||
from keystoneclient import exceptions as ks_exception
|
||||
from keystoneclient import session as ks_session
|
||||
from keystoneclient.v2_0 import client as ks_client
|
||||
|
||||
from keystoneauth1 import exceptions as ka_exception
|
||||
from keystoneauth1 import identity as ka_identity
|
||||
from keystoneauth1 import loading as ka_loading
|
||||
from keystoneclient.v3 import client as ks_client_v3
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
CFG_GROUP = "service_credentials"
|
||||
|
||||
|
||||
def get_client(conf):
|
||||
return ks_client.Client(
|
||||
username=conf.service_credentials.os_username,
|
||||
password=conf.service_credentials.os_password,
|
||||
tenant_id=conf.service_credentials.os_tenant_id,
|
||||
tenant_name=conf.service_credentials.os_tenant_name,
|
||||
cacert=conf.service_credentials.os_cacert,
|
||||
auth_url=conf.service_credentials.os_auth_url,
|
||||
region_name=conf.service_credentials.os_region_name,
|
||||
insecure=conf.service_credentials.insecure,
|
||||
timeout=conf.http_timeout,)
|
||||
def get_session(conf, requests_session=None):
|
||||
"""Get a aodh service credentials auth session."""
|
||||
auth_plugin = ka_loading.load_auth_from_conf_options(conf, CFG_GROUP)
|
||||
session = ka_loading.load_session_from_conf_options(
|
||||
conf, CFG_GROUP, auth=auth_plugin, session=requests_session
|
||||
)
|
||||
return session
|
||||
|
||||
|
||||
def get_v3_client(conf, trust_id=None):
|
||||
def get_client(conf, trust_id=None, requests_session=None):
|
||||
"""Return a client for keystone v3 endpoint, optionally using a trust."""
|
||||
auth_url = conf.service_credentials.os_auth_url
|
||||
try:
|
||||
auth_url_noneversion = auth_url.replace('/v2.0', '/')
|
||||
discover = ks_discover.Discover(auth_url=auth_url_noneversion)
|
||||
v3_auth_url = discover.url_for('3.0')
|
||||
if v3_auth_url:
|
||||
auth_url = v3_auth_url
|
||||
else:
|
||||
auth_url = auth_url
|
||||
except Exception:
|
||||
auth_url = auth_url.replace('/v2.0', '/v3')
|
||||
return ks_client_v3.Client(
|
||||
username=conf.service_credentials.os_username,
|
||||
password=conf.service_credentials.os_password,
|
||||
cacert=conf.service_credentials.os_cacert,
|
||||
auth_url=auth_url,
|
||||
region_name=conf.service_credentials.os_region_name,
|
||||
insecure=conf.service_credentials.insecure,
|
||||
timeout=conf.http_timeout,
|
||||
trust_id=trust_id)
|
||||
session = get_session(conf, requests_session=requests_session)
|
||||
return ks_client_v3.Client(session=session, trust_id=trust_id)
|
||||
|
||||
|
||||
def create_trust_id(conf, trustor_user_id, trustor_project_id,
|
||||
roles, auth_plugin):
|
||||
def get_service_catalog(client):
|
||||
return client.session.auth.get_access(client.session).service_catalog
|
||||
|
||||
|
||||
def get_auth_token(client):
|
||||
return client.session.auth.get_access(client.session).auth_token
|
||||
|
||||
|
||||
def get_client_on_behalf_user(conf, auth_plugin, trust_id=None,
|
||||
requests_session=None):
|
||||
"""Return a client for keystone v3 endpoint, optionally using a trust."""
|
||||
session = ka_loading.load_session_from_conf_options(
|
||||
conf, CFG_GROUP, auth=auth_plugin, session=requests_session
|
||||
)
|
||||
return ks_client_v3.Client(session=session, trust_id=trust_id)
|
||||
|
||||
|
||||
def create_trust_id(conf, trustor_user_id, trustor_project_id, roles,
|
||||
auth_plugin):
|
||||
"""Create a new trust using the aodh service user."""
|
||||
admin_client = get_v3_client(conf)
|
||||
|
||||
admin_client = get_client(conf)
|
||||
trustee_user_id = admin_client.auth_ref.user_id
|
||||
|
||||
session = ks_session.Session.construct({
|
||||
'cacert': conf.service_credentials.os_cacert,
|
||||
'insecure': conf.service_credentials.insecure})
|
||||
|
||||
client = ks_client_v3.Client(session=session, auth=auth_plugin)
|
||||
|
||||
client = get_client_on_behalf_user(conf, auth_plugin=auth_plugin)
|
||||
trust = client.trusts.create(trustor_user=trustor_user_id,
|
||||
trustee_user=trustee_user_id,
|
||||
project=trustor_project_id,
|
||||
@ -81,12 +77,94 @@ def create_trust_id(conf, trustor_user_id, trustor_project_id,
|
||||
|
||||
def delete_trust_id(conf, trust_id, auth_plugin):
|
||||
"""Delete a trust previously setup for the aodh user."""
|
||||
session = ks_session.Session.construct({
|
||||
'cacert': conf.service_credentials.os_cacert,
|
||||
'insecure': conf.service_credentials.insecure})
|
||||
|
||||
client = ks_client_v3.Client(session=session, auth=auth_plugin)
|
||||
client = get_client_on_behalf_user(conf, auth_plugin=auth_plugin)
|
||||
try:
|
||||
client.trusts.delete(trust_id)
|
||||
except ks_exception.NotFound:
|
||||
except ka_exception.NotFound:
|
||||
pass
|
||||
|
||||
|
||||
OPTS = [
|
||||
cfg.StrOpt('region-name',
|
||||
default=os.environ.get('OS_REGION_NAME'),
|
||||
deprecated_name="os-region-name",
|
||||
help='Region name to use for OpenStack service endpoints.'),
|
||||
cfg.StrOpt('interface',
|
||||
default=os.environ.get(
|
||||
'OS_INTERFACE', os.environ.get('OS_ENDPOINT_TYPE',
|
||||
'public')),
|
||||
deprecated_name="os-endpoint-type",
|
||||
choices=('public', 'internal', 'admin', 'auth', 'publicURL',
|
||||
'internalURL', 'adminURL'),
|
||||
help='Type of endpoint in Identity service catalog to use for '
|
||||
'communication with OpenStack services.'),
|
||||
]
|
||||
|
||||
|
||||
def register_keystoneauth_opts(conf):
|
||||
ka_loading.register_auth_conf_options(conf, CFG_GROUP)
|
||||
ka_loading.register_session_conf_options(
|
||||
conf, CFG_GROUP,
|
||||
deprecated_opts={'cacert': [
|
||||
cfg.DeprecatedOpt('os-cacert', group=CFG_GROUP),
|
||||
cfg.DeprecatedOpt('os-cacert', group="DEFAULT")]
|
||||
})
|
||||
conf.set_default("auth_type", default="password-aodh-legacy",
|
||||
group=CFG_GROUP)
|
||||
|
||||
|
||||
def setup_keystoneauth(conf):
|
||||
if conf[CFG_GROUP].auth_type == "password-aodh-legacy":
|
||||
LOG.warn("Value 'password-aodh-legacy' for '[%s]/auth_type' "
|
||||
"is deprecated. And will be removed in Aodh 3.0. "
|
||||
"Use 'password' instead.",
|
||||
CFG_GROUP)
|
||||
ka_loading.load_auth_from_conf_options(conf, CFG_GROUP)
|
||||
|
||||
|
||||
class LegacyAodhKeystoneLoader(ka_loading.BaseLoader):
|
||||
@property
|
||||
def plugin_class(self):
|
||||
return ka_identity.V2Password
|
||||
|
||||
def get_options(self):
|
||||
options = super(LegacyAodhKeystoneLoader, self).get_options()
|
||||
options.extend([
|
||||
ka_loading.Opt(
|
||||
'os-username',
|
||||
default=os.environ.get('OS_USERNAME', 'aodh'),
|
||||
help='User name to use for OpenStack service access.'),
|
||||
ka_loading.Opt(
|
||||
'os-password',
|
||||
secret=True,
|
||||
default=os.environ.get('OS_PASSWORD', 'admin'),
|
||||
help='Password to use for OpenStack service access.'),
|
||||
ka_loading.Opt(
|
||||
'os-tenant-id',
|
||||
default=os.environ.get('OS_TENANT_ID', ''),
|
||||
help='Tenant ID to use for OpenStack service access.'),
|
||||
ka_loading.Opt(
|
||||
'os-tenant-name',
|
||||
default=os.environ.get('OS_TENANT_NAME', 'admin'),
|
||||
help='Tenant name to use for OpenStack service access.'),
|
||||
ka_loading.Opt(
|
||||
'os-auth-url',
|
||||
default=os.environ.get('OS_AUTH_URL',
|
||||
'http://localhost:5000/v2.0'),
|
||||
help='Auth URL to use for OpenStack service access.'),
|
||||
])
|
||||
return options
|
||||
|
||||
def load_from_options(self, **kwargs):
|
||||
options_map = {
|
||||
'os_auth_url': 'auth_url',
|
||||
'os_username': 'username',
|
||||
'os_password': 'password',
|
||||
'os_tenant_name': 'tenant_name',
|
||||
'os_tenant_id': 'tenant_id',
|
||||
}
|
||||
identity_kwargs = dict((options_map[o.dest],
|
||||
kwargs.get(o.dest) or o.default)
|
||||
for o in self.get_options()
|
||||
if o.dest in options_map)
|
||||
return self.plugin_class(**identity_kwargs)
|
||||
|
@ -34,7 +34,7 @@ class TrustRestAlarmNotifier(rest.RestAlarmNotifier):
|
||||
reason, reason_data):
|
||||
trust_id = action.username
|
||||
|
||||
client = keystone_client.get_v3_client(self.conf, trust_id)
|
||||
client = keystone_client.get_client(self.conf, trust_id)
|
||||
|
||||
# Remove the fake user
|
||||
netloc = action.netloc.split("@")[1]
|
||||
@ -44,7 +44,7 @@ class TrustRestAlarmNotifier(rest.RestAlarmNotifier):
|
||||
action = parse.SplitResult(scheme, netloc, action.path, action.query,
|
||||
action.fragment)
|
||||
|
||||
headers = {'X-Auth-Token': client.auth_token}
|
||||
headers = {'X-Auth-Token': keystone_client.get_auth_token(client)}
|
||||
super(TrustRestAlarmNotifier, self).notify(
|
||||
action, alarm_id, alarm_name, severity, previous, current, reason,
|
||||
reason_data, headers)
|
||||
|
15
aodh/opts.py
15
aodh/opts.py
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
import itertools
|
||||
|
||||
from keystoneauth1 import loading
|
||||
from oslo_config import cfg
|
||||
|
||||
import aodh.api
|
||||
@ -22,6 +23,7 @@ import aodh.evaluator
|
||||
import aodh.evaluator.event
|
||||
import aodh.evaluator.gnocchi
|
||||
import aodh.event
|
||||
import aodh.keystone_client
|
||||
import aodh.notifier.rest
|
||||
import aodh.rpc
|
||||
import aodh.service
|
||||
@ -64,5 +66,16 @@ def list_opts():
|
||||
])),
|
||||
('coordination', aodh.coordination.OPTS),
|
||||
('database', aodh.storage.OPTS),
|
||||
('service_credentials', aodh.service.CLI_OPTS),
|
||||
('service_credentials', aodh.keystone_client.OPTS),
|
||||
]
|
||||
|
||||
|
||||
def list_keystoneauth_opts():
|
||||
# NOTE(sileht): the configuration file contains only the options
|
||||
# for the password plugin that handles keystone v2 and v3 API
|
||||
# with discovery. But other options are possible.
|
||||
# Also, the default loaded plugin is password-aodh-legacy for
|
||||
# backward compatibily
|
||||
return [('service_credentials', (
|
||||
loading.get_auth_common_conf_options() +
|
||||
loading.get_auth_plugin_conf_options('password')))]
|
||||
|
@ -14,7 +14,6 @@
|
||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
import os
|
||||
import socket
|
||||
|
||||
from oslo_config import cfg
|
||||
@ -23,6 +22,7 @@ import oslo_i18n
|
||||
from oslo_log import log
|
||||
from oslo_policy import opts as policy_opts
|
||||
|
||||
from aodh import keystone_client
|
||||
from aodh import messaging
|
||||
|
||||
|
||||
@ -47,50 +47,6 @@ OPTS = [
|
||||
]
|
||||
|
||||
|
||||
CLI_OPTS = [
|
||||
cfg.StrOpt('os-username',
|
||||
default=os.environ.get('OS_USERNAME', 'aodh'),
|
||||
help='User name to use for OpenStack service access.'),
|
||||
cfg.StrOpt('os-password',
|
||||
secret=True,
|
||||
default=os.environ.get('OS_PASSWORD', 'admin'),
|
||||
help='Password to use for OpenStack service access.'),
|
||||
cfg.StrOpt('os-tenant-id',
|
||||
default=os.environ.get('OS_TENANT_ID', ''),
|
||||
help='Tenant ID to use for OpenStack service access.'),
|
||||
cfg.StrOpt('os-tenant-name',
|
||||
default=os.environ.get('OS_TENANT_NAME', 'admin'),
|
||||
help='Tenant name to use for OpenStack service access.'),
|
||||
cfg.StrOpt('os-cacert',
|
||||
default=os.environ.get('OS_CACERT'),
|
||||
help='Certificate chain for SSL validation.'),
|
||||
cfg.StrOpt('os-auth-url',
|
||||
default=os.environ.get('OS_AUTH_URL',
|
||||
'http://localhost:5000/v2.0'),
|
||||
help='Auth URL to use for OpenStack service access.'),
|
||||
cfg.StrOpt('os-region-name',
|
||||
default=os.environ.get('OS_REGION_NAME'),
|
||||
help='Region name to use for OpenStack service endpoints.'),
|
||||
cfg.StrOpt('os-endpoint-type',
|
||||
default=os.environ.get('OS_ENDPOINT_TYPE', 'publicURL'),
|
||||
help='Type of endpoint in Identity service catalog to use for '
|
||||
'communication with OpenStack services.'),
|
||||
cfg.BoolOpt('insecure',
|
||||
default=False,
|
||||
help='Disables X.509 certificate validation when an '
|
||||
'SSL connection to Identity Service is established.'),
|
||||
cfg.StrOpt('os-user-domain-id',
|
||||
default=os.environ.get('OS_USER_DOMAIN_ID', 'default'),
|
||||
help='The domain id of the user'),
|
||||
cfg.StrOpt('os-project-domain-id',
|
||||
default=os.environ.get('OS_PROJECT_DOMAIN_ID', 'default'),
|
||||
help='The domain id of the user project'),
|
||||
cfg.StrOpt('os-project-name',
|
||||
default=os.environ.get('OS_PROJECT_NAME', 'admin'),
|
||||
help='The user project name'),
|
||||
]
|
||||
|
||||
|
||||
def prepare_service(argv=None, config_files=None):
|
||||
conf = cfg.ConfigOpts()
|
||||
oslo_i18n.enable_lazy()
|
||||
@ -105,9 +61,12 @@ def prepare_service(argv=None, config_files=None):
|
||||
for group, options in opts.list_opts():
|
||||
conf.register_opts(list(options),
|
||||
group=None if group == "DEFAULT" else group)
|
||||
keystone_client.register_keystoneauth_opts(conf)
|
||||
|
||||
conf(argv, project='aodh', validate_default_values=True,
|
||||
default_config_files=config_files)
|
||||
|
||||
keystone_client.setup_keystoneauth(conf)
|
||||
log.setup(conf, 'aodh')
|
||||
messaging.setup()
|
||||
return conf
|
||||
|
@ -1320,7 +1320,7 @@ class TestAlarms(TestAlarmsBase):
|
||||
}
|
||||
auth = mock.Mock()
|
||||
trust_client = mock.Mock()
|
||||
with mock.patch('aodh.keystone_client.get_v3_client') as client:
|
||||
with mock.patch('aodh.keystone_client.get_client') as client:
|
||||
client.return_value = mock.Mock(
|
||||
auth_ref=mock.Mock(user_id='my_user'))
|
||||
with mock.patch('keystoneclient.v3.client.Client') as sub_client:
|
||||
@ -1345,7 +1345,7 @@ class TestAlarms(TestAlarmsBase):
|
||||
else:
|
||||
self.fail("Alarm not found")
|
||||
|
||||
with mock.patch('aodh.keystone_client.get_v3_client') as client:
|
||||
with mock.patch('aodh.keystone_client.get_client') as client:
|
||||
client.return_value = mock.Mock(
|
||||
auth_ref=mock.Mock(user_id='my_user'))
|
||||
with mock.patch('keystoneclient.v3.client.Client') as sub_client:
|
||||
@ -1571,7 +1571,7 @@ class TestAlarms(TestAlarmsBase):
|
||||
data = self._get_alarm('a')
|
||||
data.update({'ok_actions': ['trust+http://something/ok']})
|
||||
trust_client = mock.Mock()
|
||||
with mock.patch('aodh.keystone_client.get_v3_client') as client:
|
||||
with mock.patch('aodh.keystone_client.get_client') as client:
|
||||
client.return_value = mock.Mock(
|
||||
auth_ref=mock.Mock(user_id='my_user'))
|
||||
with mock.patch('keystoneclient.v3.client.Client') as sub_client:
|
||||
@ -1586,7 +1586,7 @@ class TestAlarms(TestAlarmsBase):
|
||||
|
||||
data.update({'ok_actions': ['http://no-trust-something/ok']})
|
||||
|
||||
with mock.patch('aodh.keystone_client.get_v3_client') as client:
|
||||
with mock.patch('aodh.keystone_client.get_client') as client:
|
||||
client.return_value = mock.Mock(
|
||||
auth_ref=mock.Mock(user_id='my_user'))
|
||||
with mock.patch('keystoneclient.v3.client.Client') as sub_client:
|
||||
|
@ -198,7 +198,7 @@ class TestGnocchiThresholdEvaluate(base.TestEvaluatorBase):
|
||||
self.requests.post.side_effect = [avgs2]
|
||||
self._evaluate_all_alarms()
|
||||
|
||||
expected_headers = {'X-Auth-Token': 'fake_token',
|
||||
expected_headers = {'X-Auth-Token': mock.ANY,
|
||||
'Content-Type': 'application/json'}
|
||||
|
||||
start_alarm1 = "2015-01-26T12:51:00"
|
||||
|
@ -243,7 +243,7 @@ class TestAlarmNotifier(tests_base.BaseTestCase):
|
||||
url = 'http://host/action'
|
||||
|
||||
client = mock.MagicMock()
|
||||
client.auth_token = 'token_1234'
|
||||
client.session.auth.get_access.return_value.auth_token = 'token_1234'
|
||||
headers = {'X-Auth-Token': 'token_1234'}
|
||||
headers.update(self.HTTP_HEADERS)
|
||||
|
||||
|
@ -2,6 +2,7 @@
|
||||
output_file = etc/aodh/aodh.conf
|
||||
wrap_width = 79
|
||||
namespace = aodh
|
||||
namespace = aodh-auth
|
||||
namespace = oslo.db
|
||||
namespace = oslo.log
|
||||
namespace = oslo.messaging
|
||||
|
Loading…
x
Reference in New Issue
Block a user