#!/usr/bin/env python # Copyright 2011 OpenStack LLC # # 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. """ Reddwarf Command line tool """ import optparse import os import sys # If ../reddwarf/__init__.py exists, add ../ to Python search path, so that # it will override what happens to be installed in /usr/(local/)lib/python... possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), os.pardir, os.pardir)) if os.path.exists(os.path.join(possible_topdir, 'reddwarfclient', '__init__.py')): sys.path.insert(0, possible_topdir) from reddwarfclient import common class InstanceCommands(common.CommandsBase): """Commands to perform various instances operations and actions""" params = [ 'flavor', 'id', 'limit', 'marker', 'name', 'size', ] def create(self): """Create a new instance""" self._require('name', 'volume_size') # flavorRef is not required. flavorRef = self.flavor or "http://localhost:8775/v1.0/flavors/1" volume = {"size": self.size} self._pretty_print(self.dbaas.instances.create, self.name, flavorRef, volume) def delete(self): """Delete the specified instance""" self._require('id') print self.dbaas.instances.delete(self.id) def get(self): """Get details for the specified instance""" self._require('id') self._pretty_print(self.dbaas.instances.get, self.id) def list(self): """List all instances for account""" # limit and marker are not required. limit = self.limit or None if limit: limit = int(limit, 10) self._pretty_paged(self.dbaas.instances.list) def resize_volume(self): """Resize an instance volume""" self._require('id', 'size') self._pretty_print(self.dbaas.instances.resize_volume, self.id, self.size) def resize_instance(self): """Resize an instance flavor""" self._require('id', 'flavor') self._pretty_print(self.dbaas.instances.resize_instance, self.id, self.flavor_id) def restart(self): """Restart the database""" self._require('id') self._pretty_print(self.dbaas.instances.restart, self.id) class FlavorsCommands(common.CommandsBase): """Commands for listing Flavors""" params = [] def list(self): """List the available flavors""" self._pretty_print(self.dbaas.flavors.list) class DatabaseCommands(common.CommandsBase): """Database CRUD operations on an instance""" params = [ 'name', 'id', 'limit', 'marker', ] def create(self): """Create a database""" self._require('id', 'name') databases = [{'name': self.name}] print self.dbaas.databases.create(self.id, databases) def delete(self): """Delete a database""" self._require('id', 'name') print self.dbaas.databases.delete(self.id, self.name) def list(self): """List the databases""" self._require('id') self._pretty_paged(self.dbaas.databases.list, self.id) class UserCommands(common.CommandsBase): """User CRUD operations on an instance""" params = [ 'id', 'databases', 'name', 'password', ] def create(self): """Create a user in instance, with access to one or more databases""" self._require('id', 'name', 'password', 'databases') self._make_list('databases') databases = [{'name': dbname} for dbname in self.databases] users = [{'name': self.username, 'password': self.password, 'databases': databases}] self.dbaas.users.create(self.id, users) def delete(self): """Delete the specified user""" self._require('id', 'name') self.users.delete(self.id, self.name) def list(self): """List all the users for an instance""" self._require('id') self._pretty_paged(self.dbaas.users.list, self.id) class RootCommands(common.CommandsBase): """Root user related operations on an instance""" params = [ 'id', ] def create(self): """Enable the instance's root user.""" self._require('id') try: user, password = self.dbaas.root.create(self.id) print "User:\t\t%s\nPassword:\t%s" % (user, password) except: print sys.exc_info()[1] def enabled(self): """Check the instance for root access""" self._require('id') self._pretty_print(self.dbaas.root.is_root_enabled, self.id) class VersionCommands(common.CommandsBase): """List available versions""" params = [ 'url', ] def list(self): """List all the supported versions""" self._require('url') self._pretty_print(self.dbaas.versions.index, self.url) def config_options(oparser): oparser.add_option("--auth_url", default="http://localhost:5000/v2.0", help="Auth API endpoint URL with port and version. \ Default: http://localhost:5000/v2.0") oparser.add_option("--username", help="Login username") oparser.add_option("--apikey", help="Api key") oparser.add_option("--tenant_id", help="Tenant Id associated with the account") oparser.add_option("--auth_type", default="keystone", help="Auth type to support different auth environments, \ Supported values are 'keystone', 'rax'.") oparser.add_option("--service_type", default="reddwarf", help="Service type is a name associated for the catalog") oparser.add_option("--service_name", default="Reddwarf", help="Service name as provided in the service catalog") oparser.add_option("--service_url", default="", help="Service endpoint to use if the catalog doesn't \ have one") oparser.add_option("--region", default="RegionOne", help="Region the service is located in") oparser.add_option("-i", "--insecure", action="store_true", dest="insecure", default=False, help="Run in insecure mode for https endpoints.") COMMANDS = {'auth': common.Auth, 'instance': InstanceCommands, 'flavor': FlavorsCommands, 'database': DatabaseCommands, 'user': UserCommands, 'root': RootCommands, 'version': VersionCommands, } def main(): # Parse arguments oparser = optparse.OptionParser(usage="%prog [options] <cmd> <action> <args>", version='1.0', conflict_handler='resolve') config_options(oparser) for k, v in COMMANDS.items(): v._prepare_parser(oparser) (options, args) = oparser.parse_args() if not args: common.print_commands(COMMANDS) # Pop the command and check if it's in the known commands cmd = args.pop(0) if cmd in COMMANDS: fn = COMMANDS.get(cmd) command_object = fn(oparser) # Get a list of supported actions for the command actions = common.methods_of(command_object) if len(args) < 1: common.print_actions(cmd, actions) # Check for a valid action and perform that action action = args.pop(0) if action in actions: try: getattr(command_object, action)() except Exception as ex: print ex else: common.print_actions(cmd, actions) else: common.print_commands(COMMANDS) if __name__ == '__main__': main()