diff --git a/src/config/api-server/vnc_cfg_api_server.py b/src/config/api-server/vnc_cfg_api_server.py index 4987c34c301..99e08410c18 100644 --- a/src/config/api-server/vnc_cfg_api_server.py +++ b/src/config/api-server/vnc_cfg_api_server.py @@ -298,6 +298,8 @@ def __init__(self, args_str=None): 'loadbalancer-healthmonitor'].generate_default_instance = False self._resource_classes[ 'virtual-ip'].generate_default_instance = False + self._resource_classes['analytics-node'].generate_default_instance = False + self._resource_classes['database-node'].generate_default_instance = False for act_res in _ACTION_RESOURCES: link = LinkObject('action', self._base_url, act_res['uri'], diff --git a/src/config/utils/SConscript b/src/config/utils/SConscript index ad1abd29be0..dcb452b3b50 100644 --- a/src/config/utils/SConscript +++ b/src/config/utils/SConscript @@ -42,6 +42,8 @@ utils_scripts = [ 'service-instance.py', 'config_db_obj_name_validate.sh', 'config_db_obj_name_validate.py', + 'provision_analytics_node.py', + 'provision_database_node.py', ] for utils in utils_scripts: diff --git a/src/config/utils/provision_analytics_node.py b/src/config/utils/provision_analytics_node.py new file mode 100755 index 00000000000..458da2d45c9 --- /dev/null +++ b/src/config/utils/provision_analytics_node.py @@ -0,0 +1,160 @@ +#!/usr/bin/python +# +# Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. +# + +import sys +import time +import argparse +import ConfigParser + +from vnc_api.vnc_api import * +from cfgm_common.exceptions import * + + +class AnalyticsNodeProvisioner(object): + + def __init__(self, args_str=None): + self._args = None + if not args_str: + args_str = ' '.join(sys.argv[1:]) + self._parse_args(args_str) + + connected = False + tries = 0 + while not connected: + try: + self._vnc_lib = VncApi( + self._args.admin_user, self._args.admin_password, + self._args.admin_tenant_name, + self._args.api_server_ip, + self._args.api_server_port, '/', + auth_host=self._args.openstack_ip) + connected = True + except ResourceExhaustionError: # haproxy throws 503 + if tries < 10: + tries += 1 + time.sleep(3) + else: + raise + + gsc_obj = self._vnc_lib.global_system_config_read( + fq_name=['default-global-system-config']) + self._global_system_config_obj = gsc_obj + + if self._args.oper == 'add': + self.add_analytics_node() + elif self._args.oper == 'del': + self.del_analytics_node() + else: + print "Unknown operation %s. Only 'add' and 'del' supported"\ + % (self._args.oper) + + # end __init__ + + def _parse_args(self, args_str): + ''' + Eg. python provision_analytics_node.py --host_name a3s30.contrail.juniper.net + --host_ip 10.1.1.1 + --api_server_ip 127.0.0.1 + --api_server_port 8082 + --oper + ''' + + # Source any specified config/ini file + # Turn off help, so we print all options in response to -h + conf_parser = argparse.ArgumentParser(add_help=False) + + conf_parser.add_argument("-c", "--conf_file", + help="Specify config file", metavar="FILE") + args, remaining_argv = conf_parser.parse_known_args(args_str.split()) + + defaults = { + 'api_server_ip': '127.0.0.1', + 'api_server_port': '8082', + 'oper': 'add', + } + ksopts = { + 'admin_user': 'user1', + 'admin_password': 'password1', + 'admin_tenant_name': 'default-domain' + } + + if args.conf_file: + config = ConfigParser.SafeConfigParser() + config.read([args.conf_file]) + defaults.update(dict(config.items("DEFAULTS"))) + if 'KEYSTONE' in config.sections(): + ksopts.update(dict(config.items("KEYSTONE"))) + + # Override with CLI options + # Don't surpress add_help here so it will handle -h + parser = argparse.ArgumentParser( + # Inherit options from config_parser + parents=[conf_parser], + # print script description with -h/--help + description=__doc__, + # Don't mess with format of description + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + defaults.update(ksopts) + parser.set_defaults(**defaults) + + parser.add_argument( + "--host_name", help="hostname name of analytics node", required=True) + parser.add_argument("--host_ip", help="IP address of analytics node", required=True) + parser.add_argument( + "--api_server_ip", help="IP address of api server", required=True) + parser.add_argument("--api_server_port", help="Port of api server") + parser.add_argument( + "--oper", default='add', + help="Provision operation to be done(add or del)") + parser.add_argument( + "--admin_user", help="Name of keystone admin user") + parser.add_argument( + "--admin_password", help="Password of keystone admin user") + parser.add_argument( + "--admin_tenant_name", help="Tenamt name for keystone admin user") + parser.add_argument( + "--openstack_ip", help="IP address of openstack node") + + self._args = parser.parse_args(remaining_argv) + + # end _parse_args + + def add_analytics_node(self): + gsc_obj = self._global_system_config_obj + + analytics_node_obj = AnalyticsNode( + self._args.host_name, gsc_obj, + analytics_node_ip_address=self._args.host_ip) + analytics_node_exists = True + try: + analytics_node_obj = self._vnc_lib.analytics_node_read( + fq_name=analytics_node_obj.get_fq_name()) + except NoIdError: + analytics_node_exists = False + + if analytics_node_exists: + self._vnc_lib.analytics_node_update(analytics_node_obj) + else: + self._vnc_lib.analytics_node_create(analytics_node_obj) + + # end add_analytics_node + + def del_analytics_node(self): + gsc_obj = self._global_system_config_obj + analytics_node_obj = AnalyticsNode(self._args.host_name, gsc_obj) + self._vnc_lib.analytics_node_delete( + fq_name=analytics_node_obj.get_fq_name()) + # end del_analytics_node + +# end class AnalyticsNodeProvisioner + + +def main(args_str=None): + AnalyticsNodeProvisioner(args_str) +# end main + +if __name__ == "__main__": + main() diff --git a/src/config/utils/provision_database_node.py b/src/config/utils/provision_database_node.py new file mode 100755 index 00000000000..7455d805064 --- /dev/null +++ b/src/config/utils/provision_database_node.py @@ -0,0 +1,160 @@ +#!/usr/bin/python +# +# Copyright (c) 2013 Juniper Networks, Inc. All rights reserved. +# + +import sys +import time +import argparse +import ConfigParser + +from vnc_api.vnc_api import * +from cfgm_common.exceptions import * + + +class DatabaseNodeProvisioner(object): + + def __init__(self, args_str=None): + self._args = None + if not args_str: + args_str = ' '.join(sys.argv[1:]) + self._parse_args(args_str) + + connected = False + tries = 0 + while not connected: + try: + self._vnc_lib = VncApi( + self._args.admin_user, self._args.admin_password, + self._args.admin_tenant_name, + self._args.api_server_ip, + self._args.api_server_port, '/', + auth_host=self._args.openstack_ip) + connected = True + except ResourceExhaustionError: # haproxy throws 503 + if tries < 10: + tries += 1 + time.sleep(3) + else: + raise + + gsc_obj = self._vnc_lib.global_system_config_read( + fq_name=['default-global-system-config']) + self._global_system_config_obj = gsc_obj + + if self._args.oper == 'add': + self.add_database_node() + elif self._args.oper == 'del': + self.del_database_node() + else: + print "Unknown operation %s. Only 'add' and 'del' supported"\ + % (self._args.oper) + + # end __init__ + + def _parse_args(self, args_str): + ''' + Eg. python provision_database_node.py --host_name a3s30.contrail.juniper.net + --host_ip 10.1.1.1 + --api_server_ip 127.0.0.1 + --api_server_port 8082 + --oper + ''' + + # Source any specified config/ini file + # Turn off help, so we print all options in response to -h + conf_parser = argparse.ArgumentParser(add_help=False) + + conf_parser.add_argument("-c", "--conf_file", + help="Specify config file", metavar="FILE") + args, remaining_argv = conf_parser.parse_known_args(args_str.split()) + + defaults = { + 'api_server_ip': '127.0.0.1', + 'api_server_port': '8082', + 'oper': 'add', + } + ksopts = { + 'admin_user': 'user1', + 'admin_password': 'password1', + 'admin_tenant_name': 'default-domain' + } + + if args.conf_file: + config = ConfigParser.SafeConfigParser() + config.read([args.conf_file]) + defaults.update(dict(config.items("DEFAULTS"))) + if 'KEYSTONE' in config.sections(): + ksopts.update(dict(config.items("KEYSTONE"))) + + # Override with CLI options + # Don't surpress add_help here so it will handle -h + parser = argparse.ArgumentParser( + # Inherit options from config_parser + parents=[conf_parser], + # print script description with -h/--help + description=__doc__, + # Don't mess with format of description + formatter_class=argparse.RawDescriptionHelpFormatter, + ) + defaults.update(ksopts) + parser.set_defaults(**defaults) + + parser.add_argument( + "--host_name", help="hostname name of database node", required=True) + parser.add_argument("--host_ip", help="IP address of database node", required=True) + parser.add_argument( + "--api_server_ip", help="IP address of api server", required=True) + parser.add_argument("--api_server_port", help="Port of api server") + parser.add_argument( + "--oper", default='add', + help="Provision operation to be done(add or del)") + parser.add_argument( + "--admin_user", help="Name of keystone admin user") + parser.add_argument( + "--admin_password", help="Password of keystone admin user") + parser.add_argument( + "--admin_tenant_name", help="Tenamt name for keystone admin user") + parser.add_argument( + "--openstack_ip", help="IP address of openstack node") + + self._args = parser.parse_args(remaining_argv) + + # end _parse_args + + def add_database_node(self): + gsc_obj = self._global_system_config_obj + + database_node_obj = DatabaseNode( + self._args.host_name, gsc_obj, + database_node_ip_address=self._args.host_ip) + database_node_exists = True + try: + database_node_obj = self._vnc_lib.database_node_read( + fq_name=database_node_obj.get_fq_name()) + except NoIdError: + database_node_exists = False + + if database_node_exists: + self._vnc_lib.database_node_update(database_node_obj) + else: + self._vnc_lib.database_node_create(database_node_obj) + + # end add_database_node + + def del_database_node(self): + gsc_obj = self._global_system_config_obj + database_node_obj = DatabaseNode(self._args.host_name, gsc_obj) + self._vnc_lib.database_node_delete( + fq_name=database_node_obj.get_fq_name()) + # end del_database_node + +# end class DatabaseNodeProvisioner + + +def main(args_str=None): + DatabaseNodeProvisioner(args_str) +# end main + +if __name__ == "__main__": + main() diff --git a/src/schema/vnc_cfg.xsd b/src/schema/vnc_cfg.xsd index bf705a9c7e2..fbeaa5d4f55 100644 --- a/src/schema/vnc_cfg.xsd +++ b/src/schema/vnc_cfg.xsd @@ -1364,6 +1364,26 @@ targetNamespace="http://www.contrailsystems.com/2012/VNC-CONFIG/0"> Link('logical-router-service-instance', 'logical-router', 'service-instance', ['ref']) --> + + + + + + + + + + + + + +