diff --git a/releasenotes/notes/add-creating-ns-vnffg-from-template-213eee7f1820aa0c.yaml b/releasenotes/notes/add-creating-ns-vnffg-from-template-213eee7f1820aa0c.yaml new file mode 100644 index 00000000..a382a5e1 --- /dev/null +++ b/releasenotes/notes/add-creating-ns-vnffg-from-template-213eee7f1820aa0c.yaml @@ -0,0 +1,5 @@ +--- +features: + - | + Support to create directly VNFFG and NS from its descriptor template + without creating VNFFGD and NSD. \ No newline at end of file diff --git a/tackerclient/tacker/v1_0/nfvo/ns.py b/tackerclient/tacker/v1_0/nfvo/ns.py index 3427e7f8..a3bc65da 100644 --- a/tackerclient/tacker/v1_0/nfvo/ns.py +++ b/tackerclient/tacker/v1_0/nfvo/ns.py @@ -51,6 +51,9 @@ class CreateNS(tackerV10.CreateCommand): nsd_group.add_argument( '--nsd-id', help=_('NSD ID to use as template to create NS')) + nsd_group.add_argument( + '--nsd-template', + help=_('NSD file to create NS')) nsd_group.add_argument( '--nsd-name', help=_('NSD name to use as template to create NS')) @@ -89,6 +92,17 @@ class CreateNS(tackerV10.CreateCommand): parsed_args. nsd_name) parsed_args.nsd_id = _id + elif parsed_args.nsd_template: + with open(parsed_args.nsd_template) as f: + template = f.read() + try: + args['nsd_template'] = yaml.load( + template, Loader=yaml.SafeLoader) + except yaml.YAMLError as e: + raise exceptions.InvalidInput(e) + if not args['nsd_template']: + raise exceptions.InvalidInput('The nsd file is empty') + if parsed_args.param_file: with open(parsed_args.param_file) as f: param_yaml = f.read() diff --git a/tackerclient/tacker/v1_0/nfvo/nsd.py b/tackerclient/tacker/v1_0/nfvo/nsd.py index 1dc24588..85f6bd5b 100644 --- a/tackerclient/tacker/v1_0/nfvo/nsd.py +++ b/tackerclient/tacker/v1_0/nfvo/nsd.py @@ -26,7 +26,24 @@ class ListNSD(tackerV10.ListCommand): """List NSDs that belong to a given tenant.""" resource = _NSD - list_columns = ['id', 'name', 'description'] + list_columns = ['id', 'name', 'template_source', 'description'] + + def get_parser(self, prog_name): + parser = super(ListNSD, self).get_parser(prog_name) + parser.add_argument( + '--template-source', + help=_("List NSD with specified template source. Available \ + options are 'onboared' (default), 'inline' or 'all'"), + action='store', + default='onboarded') + return parser + + def args2search_opts(self, parsed_args): + search_opts = super(ListNSD, self).args2search_opts(parsed_args) + template_source = parsed_args.template_source + if parsed_args.template_source: + search_opts.update({'template_source': template_source}) + return search_opts class ShowNSD(tackerV10.ShowCommand): diff --git a/tackerclient/tacker/v1_0/nfvo/vnffg.py b/tackerclient/tacker/v1_0/nfvo/vnffg.py index 92b98ed2..355d1063 100644 --- a/tackerclient/tacker/v1_0/nfvo/vnffg.py +++ b/tackerclient/tacker/v1_0/nfvo/vnffg.py @@ -92,6 +92,9 @@ class CreateVNFFG(tackerV10.CreateCommand): vnffgd_group.add_argument( '--vnffgd-name', help=_('VNFFGD Name to use as template to create VNFFG')) + vnffgd_group.add_argument( + '--vnffgd-template', + help=_('VNFFGD file to create VNFFG')) parser.add_argument( '--vnf-mapping', help=_('List of logical VNFD name to VNF instance name mapping. ' @@ -130,6 +133,16 @@ class CreateVNFFG(tackerV10.CreateCommand): parsed_args. vnffgd_name) parsed_args.vnffgd_id = _id + elif parsed_args.vnffgd_template: + with open(parsed_args.vnffgd_template) as f: + template = f.read() + try: + args['vnffgd_template'] = yaml.load( + template, Loader=yaml.SafeLoader) + except yaml.YAMLError as e: + raise exceptions.InvalidInput(e) + if not args['vnffgd_template']: + raise exceptions.InvalidInput('The vnffgd file is empty') if parsed_args.param_file: with open(parsed_args.param_file) as f: diff --git a/tackerclient/tacker/v1_0/nfvo/vnffgd.py b/tackerclient/tacker/v1_0/nfvo/vnffgd.py index 40a0b804..1bbe7ccd 100644 --- a/tackerclient/tacker/v1_0/nfvo/vnffgd.py +++ b/tackerclient/tacker/v1_0/nfvo/vnffgd.py @@ -26,7 +26,24 @@ class ListVNFFGD(tackerV10.ListCommand): """List VNFFGDs that belong to a given tenant.""" resource = _VNFFGD - list_columns = ['id', 'name', 'description'] + list_columns = ['id', 'name', 'template_source', 'description'] + + def get_parser(self, prog_name): + parser = super(ListVNFFGD, self).get_parser(prog_name) + parser.add_argument( + '--template-source', + help=_("List VNFFGD with specified template source. Available \ + options are 'onboarded' (default), 'inline' or 'all'"), + action='store', + default='onboarded') + return parser + + def args2search_opts(self, parsed_args): + search_opts = super(ListVNFFGD, self).args2search_opts(parsed_args) + template_source = parsed_args.template_source + if parsed_args.template_source: + search_opts.update({'template_source': template_source}) + return search_opts class ShowVNFFGD(tackerV10.ShowCommand): diff --git a/tackerclient/tests/unit/vm/test_cli10_vnffgd.py b/tackerclient/tests/unit/vm/test_cli10_vnffgd.py index 6345330f..652e9b61 100644 --- a/tackerclient/tests/unit/vm/test_cli10_vnffgd.py +++ b/tackerclient/tests/unit/vm/test_cli10_vnffgd.py @@ -76,11 +76,23 @@ class CLITestV10VmVNFFGDJSON(test_cli10.CLITestV10Base): def test_list_vnffgds(self): cmd = vnffgd.ListVNFFGD(test_cli10.MyApp(sys.stdout), None) - self._test_list_resources(self._RESOURCES, cmd, True) + self._test_list_resources(self._RESOURCES, cmd, True, + template_source='onboarded') + + def test_list_inline_vnffgds(self): + cmd = vnffgd.ListVNFFGD(test_cli10.MyApp(sys.stdout), None) + self._test_list_resources(self._RESOURCES, cmd, True, + template_source='inline') + + def test_list_all_vnffgds(self): + cmd = vnffgd.ListVNFFGD(test_cli10.MyApp(sys.stdout), None) + self._test_list_resources(self._RESOURCES, cmd, True, + template_source='all') def test_list_vnffgds_pagenation(self): cmd = vnffgd.ListVNFFGD(test_cli10.MyApp(sys.stdout), None) - self._test_list_resources(self._RESOURCES, cmd, True) + self._test_list_resources(self._RESOURCES, cmd, True, + template_source='onboarded') def test_show_vnffgd_id(self): cmd = vnffgd.ShowVNFFGD(test_cli10.MyApp(sys.stdout), None)