Michael Basnight fd43cbd73b Massive refactoring to the troveclient
The new client adheres to the standards of the other clients
now. It prints out tables, uses ENVVAR's for auth, no longer
stores pickled json in a login token, uses openstack common,
and moves the cli operations into a v1 module for the future
of trove when it has a v2 api.

Please note for compatibility, the troveclient.compat module
has the old cli. In order to deploy it, amend the setup.cfg
to include the compat module.

implements blueprint cli-compliance-upgrade

Change-Id: Ie69d9dbc75ce90496da316244c97acca1877a327
2013-10-09 19:21:08 -07:00

148 lines
5.7 KiB
Python

# Copyright (c) 2011 OpenStack Foundation
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
from troveclient import base
from troveclient.v1 import databases
from troveclient.common import check_for_exceptions
from troveclient.common import limit_url
from troveclient.common import Paginated
from troveclient.common import quote_user_host
import urlparse
class User(base.Resource):
"""
A database user
"""
def __repr__(self):
return "<User: %s>" % self.name
class Users(base.ManagerWithFind):
"""
Manage :class:`Users` resources.
"""
resource_class = User
def create(self, instance_id, users):
"""
Create users with permissions to the specified databases
"""
body = {"users": users}
url = "/instances/%s/users" % instance_id
resp, body = self.api.client.post(url, body=body)
check_for_exceptions(resp, body)
def delete(self, instance_id, username, hostname=None):
"""Delete an existing user in the specified instance"""
user = quote_user_host(username, hostname)
url = "/instances/%s/users/%s" % (instance_id, user)
resp, body = self.api.client.delete(url)
check_for_exceptions(resp, body)
def _list(self, url, response_key, limit=None, marker=None):
resp, body = self.api.client.get(limit_url(url, limit, marker))
check_for_exceptions(resp, body)
if not body:
raise Exception("Call to " + url +
" did not return a body.")
links = body.get('links', [])
next_links = [link['href'] for link in links if link['rel'] == 'next']
next_marker = None
for link in next_links:
# Extract the marker from the url.
parsed_url = urlparse.urlparse(link)
query_dict = dict(urlparse.parse_qsl(parsed_url.query))
next_marker = query_dict.get('marker', None)
users = [self.resource_class(self, res) for res in body[response_key]]
return Paginated(users, next_marker=next_marker, links=links)
def list(self, instance, limit=None, marker=None):
"""
Get a list of all Users from the instance's Database.
:rtype: list of :class:`User`.
"""
return self._list("/instances/%s/users" % base.getid(instance),
"users", limit, marker)
def get(self, instance_id, username, hostname=None):
"""
Get a single User from the instance's Database.
:rtype: :class:`User`.
"""
user = quote_user_host(username, hostname)
url = "/instances/%s/users/%s" % (instance_id, user)
return self._get(url, "user")
def update_attributes(self, instance, username, newuserattr=None,
hostname=None):
"""
Update attributes of a single User in an instance.
:rtype: :class:`User`.
"""
instance_id = base.getid(instance)
user = quote_user_host(username, hostname)
user_dict = {}
if not newuserattr:
newuserattr = {}
else:
user_dict['user'] = newuserattr
url = "/instances/%s/users/%s" % (instance_id, user)
resp, body = self.api.client.put(url, body=user_dict)
check_for_exceptions(resp, body)
def list_access(self, instance, username, hostname=None):
"""Show all databases the given user has access to. """
instance_id = base.getid(instance)
user = quote_user_host(username, hostname)
url = "/instances/%(instance_id)s/users/%(user)s/databases"
local_vars = locals()
resp, body = self.api.client.get(url % local_vars)
check_for_exceptions(resp, body)
if not body:
raise Exception("Call to %s did not return to a body" % url)
return [databases.Database(self, db) for db in body['databases']]
def grant(self, instance, username, databases, hostname=None):
"""Allow an existing user permissions to access a database."""
instance_id = base.getid(instance)
user = quote_user_host(username, hostname)
url = "/instances/%(instance_id)s/users/%(user)s/databases"
dbs = {'databases': [{'name': db} for db in databases]}
local_vars = locals()
resp, body = self.api.client.put(url % local_vars, body=dbs)
check_for_exceptions(resp, body)
def revoke(self, instance, username, database, hostname=None):
"""Revoke from an existing user access permissions to a database."""
instance_id = base.getid(instance)
user = quote_user_host(username, hostname)
url = ("/instances/%(instance_id)s/users/%(user)s/"
"databases/%(database)s")
local_vars = locals()
resp, body = self.api.client.delete(url % local_vars)
check_for_exceptions(resp, body)
def change_passwords(self, instance, users):
"""Change the password for one or more users."""
instance_id = base.getid(instance)
user_dict = {"users": users}
url = "/instances/%s/users" % instance_id
resp, body = self.api.client.put(url, body=user_dict)
check_for_exceptions(resp, body)