diff --git a/gyanclient/common/utils.py b/gyanclient/common/utils.py index 72370f9..ac5dc06 100644 --- a/gyanclient/common/utils.py +++ b/gyanclient/common/utils.py @@ -129,6 +129,13 @@ def list_hosts(hosts): {'versions': print_list_field('versions')}, sortby_index=None) +def list_flavors(flavors): + columns = ('id', 'name', 'driver', 'cpu', 'memory', 'disk') + utils.print_list(flavors, columns, + {'versions': print_list_field('versions')}, + sortby_index=None) + + def list_models(models): columns = ('id', 'name', 'status', 'ml_type', 'url', diff --git a/gyanclient/v1/client.py b/gyanclient/v1/client.py index 5c3b639..9805a92 100644 --- a/gyanclient/v1/client.py +++ b/gyanclient/v1/client.py @@ -14,6 +14,7 @@ from keystoneauth1 import loading from keystoneauth1 import session as ksa_session from gyanclient.common import httpclient +from gyanclient.v1 import flavors from gyanclient.v1 import hosts from gyanclient.v1 import models from gyanclient.v1 import versions @@ -116,6 +117,7 @@ class Client(object): session=session, api_version=api_version, **client_kwargs) + self.flavors = flavors.FlavorManager(self.http_client) self.hosts = hosts.HostManager(self.http_client) self.models = models.ModelManager(self.http_client) self.versions = versions.VersionManager(self.http_client) diff --git a/gyanclient/v1/flavors.py b/gyanclient/v1/flavors.py new file mode 100644 index 0000000..9bd4268 --- /dev/null +++ b/gyanclient/v1/flavors.py @@ -0,0 +1,67 @@ +# 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 six.moves.urllib import parse + +from gyanclient import api_versions +from gyanclient.common import base +from gyanclient.common import utils +from gyanclient import exceptions + + +class Flavor(base.Resource): + def __repr__(self): + return "<Flavor %s>" % self._info + + +class FlavorManager(base.Manager): + resource_class = Flavor + + @staticmethod + def _path(id=None): + + if id: + return '/v1/flavors/%s' % id + else: + return '/v1/flavors' + + def list_flavors(self, **kwargs): + """Retrieve a list of Flavors. + + :returns: A list of flavors. + + """ + + return self._list_pagination(self._path(''), + "flavors") + + def get(self, id): + try: + return self._list(self._path(id))[0] + except IndexError: + return None + + def flavor_create(self, **kwargs): + new = { + "python_version": kwargs["hints_data"]["python_version"], + "cpu": kwargs["hints_data"]["cpu"], + "memory": kwargs["hints_data"]["memory"], + "disk": kwargs["hints_data"]["disk"], + "driver": kwargs["hints_data"]["driver"], + "additional_details": kwargs["hints_data"]["additional_details"] + } + new["name"] = kwargs["name"] + + return self._create(self._path(), new) + + def delete_flavor(self, id): + return self._delete(self._path(id)) diff --git a/gyanclient/v1/flavors_shell.py b/gyanclient/v1/flavors_shell.py new file mode 100644 index 0000000..74595aa --- /dev/null +++ b/gyanclient/v1/flavors_shell.py @@ -0,0 +1,77 @@ +# 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. + +import argparse +from contextlib import closing +import io +import json +import os +import tarfile +import time +import yaml + +from gyanclient.common import cliutils as utils +from gyanclient.common import utils as gyan_utils +from gyanclient import exceptions as exc + + +def _show_flavor(flavor): + utils.print_dict(flavor._info) + + +@utils.arg('flavor_id', + metavar='<flavor-id>', + help='ID of the Flavor to delete.') +def do_flavor_delete(cs, args): + """Delete specified flavor.""" + try: + cs.flavors.delete_flavor(args.flavor_id) + print("Request to delete flavor %s has been accepted." % + args.flavor_id) + except Exception as e: + print("Delete for flavor %(flavor)s failed: %(e)s" % + {'flavor': args.flavor_id, 'e': e}) + + +@utils.arg('flavor_id', + metavar='<flavor-id>', + help='ID or name of the flavor to show.') +def do_flavor_show(cs, args): + """Show details of a flavors.""" + flavor = cs.flavors.get(args.flavor_id) + _show_flavor(flavor) + + +def do_flavor_list(cs, args): + """List flavors""" + flavors = cs.flavors.list_flavors() + gyan_utils.list_flavors(flavors) + + +@utils.arg('name', + metavar='<name>', + help='ID or name of the flavor to train') +@utils.arg('--hints-path', + metavar='<hints_path>', + help='Absolute path for trained flavors') +def do_flavor_create(cs, args): + """Upload and create a trained flavor""" + opts = {} + opts['name'] = args.name + opts['hints_data'] = yaml.load(open(args.hints_path)) + opts = gyan_utils.remove_null_parms(**opts) + try: + flavors = cs.flavors.flavor_create(**opts) + gyan_utils.list_flavors([flavors]) + except Exception as e: + print("Creation of flavor %(flavor)s " + "failed: %(e)s" % {'flavor': args.name, 'e': e}) diff --git a/gyanclient/v1/shell.py b/gyanclient/v1/shell.py index 70254d5..4d51a57 100644 --- a/gyanclient/v1/shell.py +++ b/gyanclient/v1/shell.py @@ -12,10 +12,12 @@ from gyanclient.v1 import hosts_shell from gyanclient.v1 import models_shell +from gyanclient.v1 import flavors_shell from gyanclient.v1 import versions_shell COMMAND_MODULES = [ hosts_shell, models_shell, + flavors_shell, versions_shell ]