Add Neutron flavor framework CLI
Provide command line control of Neutron flavor framework resources, adding the following: flavor-create flavor-delete flavor-list flavor-show flavor-update flavor-profile-create flavor-profile-delete flavor-profile-list flavor-profile-show flavor-profile-update as well as ability to manipulate flavor to profile associations: flavor-associate flavor-disassociate Change to the '--enabled {True,False}' syntax. Bump up unit test coverage. ApiImpact DocImpact Implements: blueprint neutron-flavor-framework Change-Id: I0d73c8de223659071eb305d8bd1c699aefaeeb89
This commit is contained in:
parent
2119b68610
commit
a150ce000d
0
neutronclient/neutron/v2_0/flavor/__init__.py
Normal file
0
neutronclient/neutron/v2_0/flavor/__init__.py
Normal file
167
neutronclient/neutron/v2_0/flavor/flavor.py
Normal file
167
neutronclient/neutron/v2_0/flavor/flavor.py
Normal file
@ -0,0 +1,167 @@
|
|||||||
|
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
# 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 __future__ import print_function
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from neutronclient.common import utils
|
||||||
|
from neutronclient.i18n import _
|
||||||
|
from neutronclient.neutron import v2_0 as neutronV20
|
||||||
|
|
||||||
|
|
||||||
|
class ListFlavor(neutronV20.ListCommand):
|
||||||
|
"""List Neutron service flavors."""
|
||||||
|
|
||||||
|
resource = 'flavor'
|
||||||
|
list_columns = ['id', 'name', 'service_type', 'enabled']
|
||||||
|
pagination_support = True
|
||||||
|
sorting_support = True
|
||||||
|
|
||||||
|
|
||||||
|
class ShowFlavor(neutronV20.ShowCommand):
|
||||||
|
"""Show information about a given Neutron service flavor."""
|
||||||
|
|
||||||
|
resource = 'flavor'
|
||||||
|
|
||||||
|
|
||||||
|
class CreateFlavor(neutronV20.CreateCommand):
|
||||||
|
"""Create a Neutron service flavor."""
|
||||||
|
|
||||||
|
resource = 'flavor'
|
||||||
|
|
||||||
|
def add_known_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'name',
|
||||||
|
metavar='NAME',
|
||||||
|
help=_('Name for the flavor.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'service_type',
|
||||||
|
metavar='SERVICE_TYPE',
|
||||||
|
help=_('Service type to which the flavor applies to: e.g. VPN. '
|
||||||
|
'(See service-provider-list for loaded examples.)'))
|
||||||
|
parser.add_argument(
|
||||||
|
'--description',
|
||||||
|
help=_('Description for the flavor.'))
|
||||||
|
utils.add_boolean_argument(
|
||||||
|
parser,
|
||||||
|
'--enabled',
|
||||||
|
default=argparse.SUPPRESS,
|
||||||
|
help=_('Sets enabled flag.'))
|
||||||
|
|
||||||
|
def args2body(self, parsed_args):
|
||||||
|
body = {}
|
||||||
|
neutronV20.update_dict(parsed_args, body,
|
||||||
|
['name', 'description', 'service_type',
|
||||||
|
'enabled'])
|
||||||
|
return {self.resource: body}
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteFlavor(neutronV20.DeleteCommand):
|
||||||
|
"""Delete a given Neutron service flavor."""
|
||||||
|
|
||||||
|
resource = 'flavor'
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateFlavor(neutronV20.UpdateCommand):
|
||||||
|
"""Update a Neutron service flavor."""
|
||||||
|
|
||||||
|
resource = 'flavor'
|
||||||
|
|
||||||
|
def add_known_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'--name',
|
||||||
|
help=_('Name for the flavor.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'--description',
|
||||||
|
help=_('Description for the flavor.'))
|
||||||
|
utils.add_boolean_argument(
|
||||||
|
parser,
|
||||||
|
'--enabled',
|
||||||
|
default=argparse.SUPPRESS,
|
||||||
|
help=_('Sets enabled flag.'))
|
||||||
|
|
||||||
|
def args2body(self, parsed_args):
|
||||||
|
body = {}
|
||||||
|
neutronV20.update_dict(parsed_args, body,
|
||||||
|
['name', 'description', 'enabled'])
|
||||||
|
return {self.resource: body}
|
||||||
|
|
||||||
|
|
||||||
|
class AssociateFlavor(neutronV20.NeutronCommand):
|
||||||
|
"""Associate a Neutron service flavor with a flavor profile."""
|
||||||
|
|
||||||
|
resource = 'flavor'
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(AssociateFlavor, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
'flavor',
|
||||||
|
metavar='FLAVOR',
|
||||||
|
help=_('Name or ID of the flavor to associate.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'flavor_profile',
|
||||||
|
metavar='FLAVOR_PROFILE',
|
||||||
|
help=_('ID of the flavor profile to be associated with the '
|
||||||
|
'flavor.'))
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def run(self, parsed_args):
|
||||||
|
neutron_client = self.get_client()
|
||||||
|
neutron_client.format = parsed_args.request_format
|
||||||
|
flavor_id = neutronV20.find_resourceid_by_name_or_id(
|
||||||
|
neutron_client, 'flavor', parsed_args.flavor)
|
||||||
|
service_profile_id = neutronV20.find_resourceid_by_id(
|
||||||
|
neutron_client, 'service_profile', parsed_args.flavor_profile)
|
||||||
|
body = {'service_profile': {'id': service_profile_id}}
|
||||||
|
neutron_client.associate_flavor(flavor_id, body)
|
||||||
|
print((_('Associated flavor %(flavor)s with '
|
||||||
|
'flavor_profile %(profile)s') %
|
||||||
|
{'flavor': parsed_args.flavor,
|
||||||
|
'profile': parsed_args.flavor_profile}),
|
||||||
|
file=self.app.stdout)
|
||||||
|
|
||||||
|
|
||||||
|
class DisassociateFlavor(neutronV20.NeutronCommand):
|
||||||
|
"""Disassociate a Neutron service flavor from a flavor profile."""
|
||||||
|
|
||||||
|
resource = 'flavor'
|
||||||
|
|
||||||
|
def get_parser(self, prog_name):
|
||||||
|
parser = super(DisassociateFlavor, self).get_parser(prog_name)
|
||||||
|
parser.add_argument(
|
||||||
|
'flavor',
|
||||||
|
metavar='FLAVOR',
|
||||||
|
help=_('Name or ID of the flavor.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'flavor_profile',
|
||||||
|
metavar='FLAVOR_PROFILE',
|
||||||
|
help=_('ID of the flavor profile to be disassociated from the '
|
||||||
|
'flavor.'))
|
||||||
|
return parser
|
||||||
|
|
||||||
|
def run(self, parsed_args):
|
||||||
|
neutron_client = self.get_client()
|
||||||
|
neutron_client.format = parsed_args.request_format
|
||||||
|
flavor_id = neutronV20.find_resourceid_by_name_or_id(
|
||||||
|
neutron_client, 'flavor', parsed_args.flavor)
|
||||||
|
service_profile_id = neutronV20.find_resourceid_by_id(
|
||||||
|
neutron_client, 'service_profile', parsed_args.flavor_profile)
|
||||||
|
neutron_client.disassociate_flavor(flavor_id, service_profile_id)
|
||||||
|
print((_('Disassociated flavor %(flavor)s from '
|
||||||
|
'flavor_profile %(profile)s') %
|
||||||
|
{'flavor': parsed_args.flavor,
|
||||||
|
'profile': parsed_args.flavor_profile}),
|
||||||
|
file=self.app.stdout)
|
99
neutronclient/neutron/v2_0/flavor/flavor_profile.py
Normal file
99
neutronclient/neutron/v2_0/flavor/flavor_profile.py
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
# 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.
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
from neutronclient.common import utils
|
||||||
|
from neutronclient.i18n import _
|
||||||
|
from neutronclient.neutron import v2_0 as neutronV20
|
||||||
|
|
||||||
|
|
||||||
|
class ListFlavorProfile(neutronV20.ListCommand):
|
||||||
|
"""List Neutron service flavor profiles."""
|
||||||
|
|
||||||
|
resource = 'service_profile'
|
||||||
|
list_columns = ['id', 'description', 'enabled', 'metainfo']
|
||||||
|
pagination_support = True
|
||||||
|
sorting_support = True
|
||||||
|
|
||||||
|
|
||||||
|
class ShowFlavorProfile(neutronV20.ShowCommand):
|
||||||
|
"""Show information about a given Neutron service flavor profile."""
|
||||||
|
|
||||||
|
resource = 'service_profile'
|
||||||
|
|
||||||
|
|
||||||
|
class CreateFlavorProfile(neutronV20.CreateCommand):
|
||||||
|
"""Create a Neutron service flavor profile."""
|
||||||
|
|
||||||
|
resource = 'service_profile'
|
||||||
|
|
||||||
|
def add_known_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'--description',
|
||||||
|
help=_('Description for the flavor profile.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'--driver',
|
||||||
|
help=_('Python module path to driver.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'--metainfo',
|
||||||
|
help=_('Metainfo for the flavor profile.'))
|
||||||
|
utils.add_boolean_argument(
|
||||||
|
parser,
|
||||||
|
'--enabled',
|
||||||
|
default=argparse.SUPPRESS,
|
||||||
|
help=_('Sets enabled flag.'))
|
||||||
|
|
||||||
|
def args2body(self, parsed_args):
|
||||||
|
body = {}
|
||||||
|
neutronV20.update_dict(parsed_args, body,
|
||||||
|
['description', 'driver', 'enabled',
|
||||||
|
'metainfo'])
|
||||||
|
return {self.resource: body}
|
||||||
|
|
||||||
|
|
||||||
|
class DeleteFlavorProfile(neutronV20.DeleteCommand):
|
||||||
|
"""Delete a given Neutron service flavor profile."""
|
||||||
|
|
||||||
|
resource = 'service_profile'
|
||||||
|
|
||||||
|
|
||||||
|
class UpdateFlavorProfile(neutronV20.UpdateCommand):
|
||||||
|
"""Update a given Neutron service flavor profile."""
|
||||||
|
|
||||||
|
resource = 'service_profile'
|
||||||
|
|
||||||
|
def add_known_arguments(self, parser):
|
||||||
|
parser.add_argument(
|
||||||
|
'--description',
|
||||||
|
help=_('Description for the flavor profile.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'--driver',
|
||||||
|
help=_('Python module path to driver.'))
|
||||||
|
parser.add_argument(
|
||||||
|
'--metainfo',
|
||||||
|
help=_('Metainfo for the flavor profile.'))
|
||||||
|
utils.add_boolean_argument(
|
||||||
|
parser,
|
||||||
|
'--enabled',
|
||||||
|
default=argparse.SUPPRESS,
|
||||||
|
help=_('Sets enabled flag.'))
|
||||||
|
|
||||||
|
def args2body(self, parsed_args):
|
||||||
|
body = {}
|
||||||
|
neutronV20.update_dict(parsed_args, body,
|
||||||
|
['description', 'driver', 'enabled',
|
||||||
|
'metainfo'])
|
||||||
|
return {self.resource: body}
|
@ -50,6 +50,8 @@ from neutronclient.neutron.v2_0 import agent
|
|||||||
from neutronclient.neutron.v2_0 import agentscheduler
|
from neutronclient.neutron.v2_0 import agentscheduler
|
||||||
from neutronclient.neutron.v2_0 import credential
|
from neutronclient.neutron.v2_0 import credential
|
||||||
from neutronclient.neutron.v2_0 import extension
|
from neutronclient.neutron.v2_0 import extension
|
||||||
|
from neutronclient.neutron.v2_0.flavor import flavor
|
||||||
|
from neutronclient.neutron.v2_0.flavor import flavor_profile
|
||||||
from neutronclient.neutron.v2_0 import floatingip
|
from neutronclient.neutron.v2_0 import floatingip
|
||||||
from neutronclient.neutron.v2_0.fw import firewall
|
from neutronclient.neutron.v2_0.fw import firewall
|
||||||
from neutronclient.neutron.v2_0.fw import firewallpolicy
|
from neutronclient.neutron.v2_0.fw import firewallpolicy
|
||||||
@ -396,6 +398,18 @@ COMMAND_V2 = {
|
|||||||
bandwidth_limit_rule.DeleteQoSBandwidthLimitRule
|
bandwidth_limit_rule.DeleteQoSBandwidthLimitRule
|
||||||
),
|
),
|
||||||
'qos-available-rule-types': qos_rule.ListQoSRuleTypes,
|
'qos-available-rule-types': qos_rule.ListQoSRuleTypes,
|
||||||
|
'flavor-list': flavor.ListFlavor,
|
||||||
|
'flavor-show': flavor.ShowFlavor,
|
||||||
|
'flavor-create': flavor.CreateFlavor,
|
||||||
|
'flavor-delete': flavor.DeleteFlavor,
|
||||||
|
'flavor-update': flavor.UpdateFlavor,
|
||||||
|
'flavor-associate': flavor.AssociateFlavor,
|
||||||
|
'flavor-disassociate': flavor.DisassociateFlavor,
|
||||||
|
'flavor-profile-list': flavor_profile.ListFlavorProfile,
|
||||||
|
'flavor-profile-show': flavor_profile.ShowFlavorProfile,
|
||||||
|
'flavor-profile-create': flavor_profile.CreateFlavorProfile,
|
||||||
|
'flavor-profile-delete': flavor_profile.DeleteFlavorProfile,
|
||||||
|
'flavor-profile-update': flavor_profile.UpdateFlavorProfile,
|
||||||
}
|
}
|
||||||
|
|
||||||
COMMANDS = {'2.0': COMMAND_V2}
|
COMMANDS = {'2.0': COMMAND_V2}
|
||||||
|
0
neutronclient/tests/unit/flavor/__init__.py
Normal file
0
neutronclient/tests/unit/flavor/__init__.py
Normal file
154
neutronclient/tests/unit/flavor/test_cli20_flavor.py
Normal file
154
neutronclient/tests/unit/flavor/test_cli20_flavor.py
Normal file
@ -0,0 +1,154 @@
|
|||||||
|
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from neutronclient.neutron.v2_0.flavor import flavor
|
||||||
|
from neutronclient.tests.unit import test_cli20
|
||||||
|
|
||||||
|
|
||||||
|
class CLITestV20FlavorJSON(test_cli20.CLITestV20Base):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Prepare test environment."""
|
||||||
|
super(CLITestV20FlavorJSON, self).setUp(plurals={'flavors': 'flavor'})
|
||||||
|
self.register_non_admin_status_resource('flavor')
|
||||||
|
self.register_non_admin_status_resource('service_profile')
|
||||||
|
|
||||||
|
def test_create_flavor_with_missing_params(self):
|
||||||
|
"""Create test flavor with missing parameters."""
|
||||||
|
resource = 'flavor'
|
||||||
|
cmd = flavor.CreateFlavor(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
name = 'Test flavor'
|
||||||
|
myid = 'myid'
|
||||||
|
position_names = []
|
||||||
|
position_values = []
|
||||||
|
args = []
|
||||||
|
self.assertRaises(
|
||||||
|
SystemExit, self._test_create_resource,
|
||||||
|
resource, cmd, name, myid, args, position_names, position_values)
|
||||||
|
|
||||||
|
def test_create_flavor_with_mandatory_params(self):
|
||||||
|
"""Create test flavor with minimal parameters."""
|
||||||
|
resource = 'flavor'
|
||||||
|
cmd = flavor.CreateFlavor(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
name = 'Test flavor'
|
||||||
|
myid = 'myid'
|
||||||
|
service_type = 'DUMMY'
|
||||||
|
# Defaults are returned in body
|
||||||
|
position_names = ['name', 'service_type']
|
||||||
|
position_values = [name, service_type]
|
||||||
|
args = [name, service_type]
|
||||||
|
self._test_create_resource(resource, cmd, name, myid, args,
|
||||||
|
position_names, position_values)
|
||||||
|
|
||||||
|
def test_create_flavor_with_optional_params(self):
|
||||||
|
"""Create test flavor including optional parameters."""
|
||||||
|
resource = 'flavor'
|
||||||
|
cmd = flavor.CreateFlavor(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
name = 'Test flavor'
|
||||||
|
myid = 'myid'
|
||||||
|
service_type = 'DUMMY'
|
||||||
|
description = 'Test description'
|
||||||
|
position_names = ['name', 'service_type', 'description', 'enabled']
|
||||||
|
position_values = [name, service_type, description, 'False']
|
||||||
|
args = [name, service_type,
|
||||||
|
'--description', description,
|
||||||
|
'--enabled=False']
|
||||||
|
self._test_create_resource(resource, cmd, name, myid, args,
|
||||||
|
position_names, position_values)
|
||||||
|
|
||||||
|
def test_delete_flavor(self):
|
||||||
|
"""Delete flavor."""
|
||||||
|
resource = 'flavor'
|
||||||
|
cmd = flavor.DeleteFlavor(test_cli20.MyApp(sys.stdout), None)
|
||||||
|
my_id = 'my-id'
|
||||||
|
args = [my_id]
|
||||||
|
self._test_delete_resource(resource, cmd, my_id, args)
|
||||||
|
|
||||||
|
def test_list_flavors(self):
|
||||||
|
"""List flavors test."""
|
||||||
|
resources = 'flavors'
|
||||||
|
cmd = flavor.ListFlavor(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
self._test_list_resources(resources, cmd, True)
|
||||||
|
|
||||||
|
def test_list_flavors_with_pagination(self):
|
||||||
|
"""List flavors test with pagination."""
|
||||||
|
resources = 'flavors'
|
||||||
|
cmd = flavor.ListFlavor(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
self._test_list_resources_with_pagination(resources, cmd)
|
||||||
|
|
||||||
|
def test_list_flavors_with_sort(self):
|
||||||
|
"""List flavors test with sorting by name and id."""
|
||||||
|
resources = 'flavors'
|
||||||
|
cmd = flavor.ListFlavor(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
self._test_list_resources(resources, cmd,
|
||||||
|
sort_key=["name", "id"],
|
||||||
|
sort_dir=["asc", "desc"])
|
||||||
|
|
||||||
|
def test_show_flavor(self):
|
||||||
|
"""Show flavor test."""
|
||||||
|
resource = 'flavor'
|
||||||
|
cmd = flavor.ShowFlavor(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
args = ['--fields', 'id', self.test_id]
|
||||||
|
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||||
|
|
||||||
|
def test_update_flavor_with_name(self):
|
||||||
|
"""Update flavor test."""
|
||||||
|
resource = 'flavor'
|
||||||
|
cmd = flavor.UpdateFlavor(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
newname = 'Test New Name'
|
||||||
|
newdescription = 'New Description'
|
||||||
|
args = ['--name', newname,
|
||||||
|
'--description', newdescription,
|
||||||
|
'--enabled', 'False', self.test_id]
|
||||||
|
self._test_update_resource(resource, cmd, self.test_id, args,
|
||||||
|
{'name': newname,
|
||||||
|
'description': newdescription,
|
||||||
|
'enabled': 'False'})
|
||||||
|
|
||||||
|
def test_associate_flavor(self):
|
||||||
|
"""Associate flavor test."""
|
||||||
|
resource = 'service_profile'
|
||||||
|
cmd = flavor.AssociateFlavor(test_cli20.MyApp(sys.stdout), None)
|
||||||
|
flavor_id = 'flavor-id'
|
||||||
|
profile_id = 'profile-id'
|
||||||
|
name = ''
|
||||||
|
args = [flavor_id, profile_id]
|
||||||
|
position_names = ['id']
|
||||||
|
position_values = [profile_id]
|
||||||
|
self._test_create_resource(resource, cmd, name, profile_id, args,
|
||||||
|
position_names, position_values,
|
||||||
|
cmd_resource='flavor_profile_binding',
|
||||||
|
parent_id=flavor_id)
|
||||||
|
|
||||||
|
def test_disassociate_flavor(self):
|
||||||
|
"""Disassociate flavor test."""
|
||||||
|
resource = 'flavor_profile_binding'
|
||||||
|
cmd = flavor.DisassociateFlavor(test_cli20.MyApp(sys.stdout), None)
|
||||||
|
flavor_id = 'flavor-id'
|
||||||
|
profile_id = 'profile-id'
|
||||||
|
args = [flavor_id, profile_id]
|
||||||
|
self._test_delete_resource(resource, cmd, profile_id, args,
|
||||||
|
parent_id=flavor_id)
|
122
neutronclient/tests/unit/flavor/test_cli20_flavor_profile.py
Normal file
122
neutronclient/tests/unit/flavor/test_cli20_flavor_profile.py
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
# Copyright 2015 Hewlett-Packard Development Company, L.P.
|
||||||
|
# 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.
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
|
||||||
|
from neutronclient.neutron.v2_0.flavor import flavor_profile
|
||||||
|
from neutronclient.tests.unit import test_cli20
|
||||||
|
|
||||||
|
|
||||||
|
class CLITestV20FlavorProfileJSON(test_cli20.CLITestV20Base):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
"""Prepare test environment."""
|
||||||
|
super(CLITestV20FlavorProfileJSON, self).setUp(
|
||||||
|
plurals={'service_profiles': 'service_profile'})
|
||||||
|
self.register_non_admin_status_resource('service_profile')
|
||||||
|
|
||||||
|
def test_create_flavor_profile_with_mandatory_params(self):
|
||||||
|
"""Create test flavor profile test."""
|
||||||
|
resource = 'service_profile'
|
||||||
|
cmd = flavor_profile.CreateFlavorProfile(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
name = ''
|
||||||
|
description = 'Test flavor profile'
|
||||||
|
myid = 'myid'
|
||||||
|
metainfo = "{'a':'b'}"
|
||||||
|
# Defaults are returned in body
|
||||||
|
position_names = ['description', 'metainfo']
|
||||||
|
position_values = [description, metainfo]
|
||||||
|
args = ['--description', description, '--metainfo', metainfo]
|
||||||
|
self._test_create_resource(resource, cmd, name, myid, args,
|
||||||
|
position_names, position_values)
|
||||||
|
|
||||||
|
def test_create_flavor_profile_with_optional_params(self):
|
||||||
|
"""Create test flavor profile disabled test."""
|
||||||
|
resource = 'service_profile'
|
||||||
|
cmd = flavor_profile.CreateFlavorProfile(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
name = ''
|
||||||
|
description = 'Test flavor profile - disabled'
|
||||||
|
myid = 'myid'
|
||||||
|
driver = 'mydriver'
|
||||||
|
metainfo = "{'a':'b'}"
|
||||||
|
position_names = ['description', 'driver', 'metainfo', 'enabled']
|
||||||
|
position_values = [description, driver, metainfo, 'False']
|
||||||
|
args = ['--description', description, '--driver', driver,
|
||||||
|
'--metainfo', metainfo, '--enabled=False']
|
||||||
|
self._test_create_resource(resource, cmd, name, myid, args,
|
||||||
|
position_names, position_values)
|
||||||
|
|
||||||
|
def test_list_flavor_profiles(self):
|
||||||
|
"""List flavor profiles test."""
|
||||||
|
resources = 'service_profiles'
|
||||||
|
cmd = flavor_profile.ListFlavorProfile(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
self._test_list_resources(resources, cmd, True)
|
||||||
|
|
||||||
|
def test_list_flavor_profiles_with_pagination(self):
|
||||||
|
"""List flavor profiles test with pagination."""
|
||||||
|
resources = 'service_profiles'
|
||||||
|
cmd = flavor_profile.ListFlavorProfile(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
self._test_list_resources_with_pagination(resources, cmd)
|
||||||
|
|
||||||
|
def test_list_flavor_profiles_with_sort(self):
|
||||||
|
"""List flavor profiles test with sort by description."""
|
||||||
|
resources = 'service_profiles'
|
||||||
|
cmd = flavor_profile.ListFlavorProfile(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
self._test_list_resources(resources, cmd,
|
||||||
|
sort_key=["description"],
|
||||||
|
sort_dir=["asc"])
|
||||||
|
|
||||||
|
def test_show_flavor_profile(self):
|
||||||
|
"""Show flavor profile test."""
|
||||||
|
resource = 'service_profile'
|
||||||
|
cmd = flavor_profile.ShowFlavorProfile(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
args = ['--fields', 'id', self.test_id]
|
||||||
|
self._test_show_resource(resource, cmd, self.test_id, args, ['id'])
|
||||||
|
|
||||||
|
def test_update_flavor_profile(self):
|
||||||
|
"""Update flavor profile test."""
|
||||||
|
resource = 'service_profile'
|
||||||
|
cmd = flavor_profile.UpdateFlavorProfile(
|
||||||
|
test_cli20.MyApp(sys.stdout), None)
|
||||||
|
newdescription = 'Test new description'
|
||||||
|
newdriver = 'NewDriver'
|
||||||
|
newmetainfo = "{'c':'d'}"
|
||||||
|
newenabled = "False"
|
||||||
|
args = ['--description', newdescription,
|
||||||
|
'--driver', newdriver,
|
||||||
|
'--metainfo', newmetainfo,
|
||||||
|
'--enabled', newenabled,
|
||||||
|
self.test_id]
|
||||||
|
self._test_update_resource(resource, cmd, self.test_id, args,
|
||||||
|
{'description': newdescription,
|
||||||
|
'driver': newdriver,
|
||||||
|
'metainfo': newmetainfo,
|
||||||
|
'enabled': newenabled})
|
||||||
|
|
||||||
|
def test_delete_flavor_profile(self):
|
||||||
|
"""Delete flavor profile."""
|
||||||
|
resource = 'service_profile'
|
||||||
|
cmd = flavor_profile.DeleteFlavorProfile(test_cli20.MyApp(sys.stdout),
|
||||||
|
None)
|
||||||
|
my_id = 'my-id'
|
||||||
|
args = [my_id]
|
||||||
|
self._test_delete_resource(resource, cmd, my_id, args)
|
@ -437,6 +437,12 @@ class Client(ClientBase):
|
|||||||
qos_bandwidth_limit_rule_path = "/qos/policies/%s/bandwidth_limit_rules/%s"
|
qos_bandwidth_limit_rule_path = "/qos/policies/%s/bandwidth_limit_rules/%s"
|
||||||
qos_rule_types_path = "/qos/rule-types"
|
qos_rule_types_path = "/qos/rule-types"
|
||||||
qos_rule_type_path = "/qos/rule-types/%s"
|
qos_rule_type_path = "/qos/rule-types/%s"
|
||||||
|
flavors_path = "/flavors"
|
||||||
|
flavor_path = "/flavors/%s"
|
||||||
|
service_profiles_path = "/service_profiles"
|
||||||
|
service_profile_path = "/service_profiles/%s"
|
||||||
|
flavor_profile_bindings_path = flavor_path + service_profiles_path
|
||||||
|
flavor_profile_binding_path = flavor_path + service_profile_path
|
||||||
|
|
||||||
# API has no way to report plurals, so we have to hard code them
|
# API has no way to report plurals, so we have to hard code them
|
||||||
EXTED_PLURALS = {'routers': 'router',
|
EXTED_PLURALS = {'routers': 'router',
|
||||||
@ -474,6 +480,7 @@ class Client(ClientBase):
|
|||||||
'policies': 'policy',
|
'policies': 'policy',
|
||||||
'bandwidth_limit_rules': 'bandwidth_limit_rule',
|
'bandwidth_limit_rules': 'bandwidth_limit_rule',
|
||||||
'rule_types': 'rule_type',
|
'rule_types': 'rule_type',
|
||||||
|
'flavors': 'flavor',
|
||||||
}
|
}
|
||||||
|
|
||||||
@APIParamsCall
|
@APIParamsCall
|
||||||
@ -1737,6 +1744,72 @@ class Client(ClientBase):
|
|||||||
return self.delete(self.qos_bandwidth_limit_rule_path %
|
return self.delete(self.qos_bandwidth_limit_rule_path %
|
||||||
(policy, rule))
|
(policy, rule))
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def create_flavor(self, body=None):
|
||||||
|
"""Creates a new Neutron service flavor."""
|
||||||
|
return self.post(self.flavors_path, body=body)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def delete_flavor(self, flavor):
|
||||||
|
"""Deletes the specified Neutron service flavor."""
|
||||||
|
return self.delete(self.flavor_path % (flavor))
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def list_flavors(self, retrieve_all=True, **_params):
|
||||||
|
"""Fetches a list of all Neutron service flavors for a tenant."""
|
||||||
|
return self.list('flavors', self.flavors_path, retrieve_all,
|
||||||
|
**_params)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def show_flavor(self, flavor, **_params):
|
||||||
|
"""Fetches information for a certain Neutron service flavor."""
|
||||||
|
return self.get(self.flavor_path % (flavor), params=_params)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def update_flavor(self, flavor, body):
|
||||||
|
"""Update a Neutron service flavor."""
|
||||||
|
return self.put(self.flavor_path % (flavor), body=body)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def associate_flavor(self, flavor, body):
|
||||||
|
"""Associate a Neutron service flavor with a profile."""
|
||||||
|
return self.post(self.flavor_profile_bindings_path %
|
||||||
|
(flavor), body=body)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def disassociate_flavor(self, flavor, flavor_profile):
|
||||||
|
"""Disassociate a Neutron service flavor with a profile."""
|
||||||
|
return self.delete(self.flavor_profile_binding_path %
|
||||||
|
(flavor, flavor_profile))
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def create_service_profile(self, body=None):
|
||||||
|
"""Creates a new Neutron service flavor profile."""
|
||||||
|
return self.post(self.service_profiles_path, body=body)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def delete_service_profile(self, flavor_profile):
|
||||||
|
"""Deletes the specified Neutron service flavor profile."""
|
||||||
|
return self.delete(self.service_profile_path % (flavor_profile))
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def list_service_profiles(self, retrieve_all=True, **_params):
|
||||||
|
"""Fetches a list of all Neutron service flavor profiles."""
|
||||||
|
return self.list('service_profiles', self.service_profiles_path,
|
||||||
|
retrieve_all, **_params)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def show_service_profile(self, flavor_profile, **_params):
|
||||||
|
"""Fetches information for a certain Neutron service flavor profile."""
|
||||||
|
return self.get(self.service_profile_path % (flavor_profile),
|
||||||
|
params=_params)
|
||||||
|
|
||||||
|
@APIParamsCall
|
||||||
|
def update_service_profile(self, service_profile, body):
|
||||||
|
"""Update a Neutron service profile."""
|
||||||
|
return self.put(self.service_profile_path % (service_profile),
|
||||||
|
body=body)
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
"""Initialize a new client for the Neutron v2.0 API."""
|
"""Initialize a new client for the Neutron v2.0 API."""
|
||||||
super(Client, self).__init__(**kwargs)
|
super(Client, self).__init__(**kwargs)
|
||||||
|
Loading…
Reference in New Issue
Block a user