Files
python-tackerclient/tackerclient/tacker/v1_0/vm/vnf.py
Sripriya ed102cac10 cli: modify vnfd, param & config attr. to dict obj
vnfd templates, parameter and config files are sent as yaml
strings in requests body to tacker server.

Change the attributes to dictionary objects. New behavior
is applicable to tosca templates only. Also, this change may mangle
the order of nodes in tosca templates. In order to address this
concern and preserve the network interfaces order in these nodes,
there will be follow on patch (on server) to addres this.

Change-Id: I05a1d60dc643dca864aff559f37491914b1fcfc3
Partial-Bug: #1591361
2016-08-26 00:57:13 -07:00

293 lines
10 KiB
Python

#
# Copyright 2013 Intel Corporation
# 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 yaml
from tackerclient.common import utils
from tackerclient.i18n import _
from tackerclient.tacker import v1_0 as tackerV10
_VNF = 'vnf'
_RESOURCE = 'resource'
class ListVNF(tackerV10.ListCommand):
"""List VNF that belong to a given tenant."""
resource = _VNF
list_columns = ['id', 'name', 'description', 'mgmt_url', 'status',
'vim_id', 'placement_attr', 'error_reason']
class ShowVNF(tackerV10.ShowCommand):
"""Show information of a given VNF."""
resource = _VNF
class CreateVNF(tackerV10.CreateCommand):
"""Create a VNF."""
resource = _VNF
remove_output_fields = ["attributes"]
def add_known_arguments(self, parser):
parser.add_argument(
'name', metavar='NAME',
help='Set a name for the VNF')
parser.add_argument(
'--description',
help='Set description for the VNF')
vnfd_group = parser.add_mutually_exclusive_group(required=True)
vnfd_group.add_argument(
'--vnfd-id',
help='VNFD ID to use as template to create VNF')
vnfd_group.add_argument(
'--vnfd-name',
help='VNFD Name to use as template to create VNF')
vim_group = parser.add_mutually_exclusive_group()
vim_group.add_argument(
'--vim-id',
help='VIM ID to use to create VNF on the specified VIM')
vim_group.add_argument(
'--vim-name',
help='VIM name to use to create VNF on the specified VIM')
parser.add_argument(
'--vim-region-name',
help='VIM Region to use to create VNF on the specified VIM')
parser.add_argument(
'--config-file',
help='Specify config yaml file')
parser.add_argument(
'--config',
help='Specify config yaml data')
parser.add_argument(
'--param-file',
help='Specify parameter yaml file'
)
def args2body(self, parsed_args):
args = {'attributes': {}}
body = {self.resource: args}
# config arg passed as data overrides config yaml when both args passed
config = None
if parsed_args.config_file:
with open(parsed_args.config_file) as f:
config_yaml = f.read()
config = yaml.load(
config_yaml, Loader=yaml.SafeLoader)
if parsed_args.config:
config = parsed_args.config
if isinstance(config, str):
config_str = parsed_args.config.decode('unicode_escape')
config = yaml.load(config_str, Loader=yaml.SafeLoader)
utils.deprecate_warning(what='yaml as string', as_of='N',
in_favor_of='yaml as dictionary')
if config:
args['attributes']['config'] = config
if parsed_args.vim_region_name:
args.setdefault('placement_attr', {})['region_name'] = \
parsed_args.vim_region_name
tacker_client = self.get_client()
tacker_client.format = parsed_args.request_format
if parsed_args.vim_name:
_id = tackerV10.find_resourceid_by_name_or_id(tacker_client,
'vim',
parsed_args.
vim_name)
parsed_args.vim_id = _id
if parsed_args.vnfd_name:
_id = tackerV10.find_resourceid_by_name_or_id(tacker_client,
'vnfd',
parsed_args.
vnfd_name)
parsed_args.vnfd_id = _id
if parsed_args.param_file:
with open(parsed_args.param_file) as f:
param_yaml = f.read()
args['attributes']['param_values'] = yaml.load(
param_yaml, Loader=yaml.SafeLoader)
tackerV10.update_dict(parsed_args, body[self.resource],
['tenant_id', 'name', 'description',
'vnfd_id', 'vim_id'])
return body
class UpdateVNF(tackerV10.UpdateCommand):
"""Update a given VNF."""
resource = _VNF
def add_known_arguments(self, parser):
parser.add_argument(
'--config-file',
help='Specify config yaml file')
parser.add_argument(
'--config',
help='Specify config yaml data')
def args2body(self, parsed_args):
body = {self.resource: {}}
# config arg passed as data overrides config yaml when both args passed
config = None
if parsed_args.config_file:
with open(parsed_args.config_file) as f:
config_yaml = f.read()
config = yaml.load(config_yaml, Loader=yaml.SafeLoader)
if parsed_args.config:
config = parsed_args.config
if isinstance(parsed_args.config, str):
config_str = parsed_args.config.decode('unicode_escape')
config = yaml.load(config_str, Loader=yaml.SafeLoader)
utils.deprecate_warning(what='yaml as string', as_of='N',
in_favor_of='yaml as dictionary')
if config:
body[self.resource]['attributes'] = {'config': config}
tackerV10.update_dict(parsed_args, body[self.resource], ['tenant_id'])
return body
class DeleteVNF(tackerV10.DeleteCommand):
"""Delete a given VNF."""
resource = _VNF
class ListVNFResources(tackerV10.ListCommand):
"""List resources of a VNF like VDU, CP, etc."""
list_columns = ['name', 'id', 'type']
allow_names = True
resource = _VNF
def get_id(self):
if self.resource:
return self.resource.upper()
def get_parser(self, prog_name):
parser = super(ListVNFResources, self).get_parser(prog_name)
if self.allow_names:
help_str = _('ID or name of %s to look up')
else:
help_str = _('ID of %s to look up')
parser.add_argument(
'id', metavar=self.get_id(),
help=help_str % self.resource)
return parser
def get_data(self, parsed_args):
self.log.debug('get_data(%s)', parsed_args)
tacker_client = self.get_client()
tacker_client.format = parsed_args.request_format
if self.allow_names:
_id = tackerV10.find_resourceid_by_name_or_id(tacker_client,
self.resource,
parsed_args.id)
else:
_id = parsed_args.id
data = self.retrieve_list_by_id(_id, parsed_args)
self.extend_list(data, parsed_args)
return self.setup_columns(data, parsed_args)
def retrieve_list_by_id(self, id, parsed_args):
"""Retrieve a list of sub resources from Tacker server"""
tacker_client = self.get_client()
tacker_client.format = parsed_args.request_format
_extra_values = tackerV10.parse_args_to_dict(self.values_specs)
tackerV10._merge_args(self, parsed_args, _extra_values,
self.values_specs)
search_opts = self.args2search_opts(parsed_args)
search_opts.update(_extra_values)
if self.pagination_support:
page_size = parsed_args.page_size
if page_size:
search_opts.update({'limit': page_size})
if self.sorting_support:
keys = parsed_args.sort_key
if keys:
search_opts.update({'sort_key': keys})
dirs = parsed_args.sort_dir
len_diff = len(keys) - len(dirs)
if len_diff > 0:
dirs += ['asc'] * len_diff
elif len_diff < 0:
dirs = dirs[:len(keys)]
if dirs:
search_opts.update({'sort_dir': dirs})
obj_lister = getattr(tacker_client, "list_vnf_resources")
data = obj_lister(id, **search_opts)
return data.get('resources', [])
class ScaleVNF(tackerV10.TackerCommand):
"""Scale a VNF."""
api = 'nfv-orchestration'
resource = None
log = None
def get_parser(self, prog_name):
parser = super(ScaleVNF, self).get_parser(prog_name)
self.add_known_arguments(parser)
return parser
def run(self, parsed_args):
tacker_client = self.get_client()
tacker_client.format = parsed_args.request_format
body = self.args2body(parsed_args)
obj_creator = getattr(tacker_client,
"scale_vnf")
obj_creator(body["scale"].pop('vnf_id'), body)
def add_known_arguments(self, parser):
vnf_group = parser.add_mutually_exclusive_group(required=True)
vnf_group.add_argument(
'--vnf-id',
help='VNF ID')
vnf_group.add_argument(
'--vnf-name',
help='VNF name')
parser.add_argument(
'--scaling-policy-name',
help='VNF policy name used to scale')
parser.add_argument(
'--scaling-type',
help='VNF scaling type, it could be either "out" or "in"')
def args2body(self, parsed_args):
args = {}
body = {"scale": args}
if parsed_args.vnf_name:
tacker_client = self.get_client()
tacker_client.format = parsed_args.request_format
_id = tackerV10.find_resourceid_by_name_or_id(tacker_client,
'vnf',
parsed_args.
vnf_name)
parsed_args.vnf_id = _id
args['vnf_id'] = parsed_args.vnf_id
args['type'] = parsed_args.scaling_type
args['policy'] = parsed_args.scaling_policy_name
return body