def should_register_cse(client, ext_install):
    """Decides if CSE installation should register CSE to vCD.

    Returns False if CSE is already registered, or if the user declines
    registration.

    :param pyvcloud.vcd.client.Client client:
    :param str ext_install: 'skip' skips registration,
        'config' allows registration without prompting user,
        'prompt' asks user before registration.

    :return: boolean that signals whether we should register CSE to vCD.

    :rtype: bool
    """
    if ext_install == 'skip':
        return False

    ext = APIExtension(client)

    try:
        cse_info = ext.get_extension_info(CSE_NAME, namespace=CSE_NAMESPACE)
        msg = f"Found 'cse' extension on vCD, enabled={cse_info['enabled']}"
        click.secho(msg, fg='green')
        LOGGER.info(msg)
        return False
    except MissingRecordException:
        prompt_msg = "Register 'cse' as an API extension in vCD?"
        if ext_install == 'prompt' and not click.confirm(prompt_msg):
            msg = f"Skipping CSE registration."
            click.secho(msg, fg='yellow')
            LOGGER.warning(msg)
            return False

    return True
Пример #2
0
    def test_0080_update_service(self):
        """Test the method APIExtension.update_extension().

        This test passes if the routing key and exchange after execution of the
        method matches the respective test strings.
        """
        logger = Environment.get_default_logger()
        api_extension = APIExtension(TestApiExtension._client)
        ext_name = TestApiExtension._service_name
        ext_namespace = TestApiExtension._service1_namespace

        logger.debug('Updating service (name:' + ext_name + ', namespace:' +
                     ext_namespace + ').')

        test_routing_key = 'testroutingkey'
        test_exchange = 'testexchange'
        href = api_extension.update_extension(name=ext_name,
                                              namespace=ext_namespace,
                                              routing_key=test_routing_key,
                                              exchange=test_exchange)
        self.assertEqual(href, TestApiExtension._service1_href)

        ext_info = api_extension.get_extension_info(ext_name,
                                                    namespace=ext_namespace)
        self.assertEqual(ext_info['routingKey'], test_routing_key)
        self.assertEqual(ext_info['exchange'], test_exchange)
Пример #3
0
def info(ctx, name, namespace):
    try:
        restore_session(ctx)
        ext = APIExtension(ctx.obj['client'])
        stdout(ext.get_extension_info(name, namespace), ctx)
    except Exception as e:
        stderr(e, ctx)
Пример #4
0
    def test_0030_get_service_info_with_invalid_name(self):
        """Test the method APIExtension.get_extension_info().

        Invoke the method with an invalid service name.

        This test passes if the an MissingRecordException is raised by the
        method.
        """
        api_extension = APIExtension(TestApiExtension._client)
        try:
            api_extension.get_extension_info(
                name=TestApiExtension._non_existent_service_name)
            self.fail('Should not be able to fetch service ' +
                      TestApiExtension._non_existent_service_name)
        except MissingRecordException as e:
            pass
Пример #5
0
    def test_0030_get_service_info_with_invalid_name(self):
        """Test the method APIExtension.get_extension_info().

        Invoke the method with an invalid service name.

        This test passes if the an MissingRecordException is raised by the
        method.
        """
        api_extension = APIExtension(TestApiExtension._client)
        try:
            api_extension.get_extension_info(
                name=TestApiExtension._non_existent_service_name)
            self.fail('Should not be able to fetch service ' +
                      TestApiExtension._non_existent_service_name)
        except MissingRecordException:
            pass
Пример #6
0
    def test_0080_update_service(self):
        """Test the method APIExtension.update_extension().

        This test passes if the routing key and exchange after execution of the
        method matches the respective test strings.
        """
        logger = Environment.get_default_logger()
        api_extension = APIExtension(TestApiExtension._client)
        ext_name = TestApiExtension._service_name
        ext_namespace = TestApiExtension._service1_namespace

        logger.debug('Updating service (name:' +
                     ext_name + ', namespace:' +
                     ext_namespace + ').')

        test_routing_key = 'testroutingkey'
        test_exchange = 'testexchange'
        href = api_extension.update_extension(
            name=ext_name,
            namespace=ext_namespace,
            routing_key=test_routing_key,
            exchange=test_exchange)
        self.assertEqual(href, TestApiExtension._service1_href)

        ext_info = api_extension.get_extension_info(ext_name,
                                                    namespace=ext_namespace)
        self.assertEqual(ext_info['routingKey'], test_routing_key)
        self.assertEqual(ext_info['exchange'], test_exchange)
Пример #7
0
    def test_0050_get_service_info_with_invalid_namespace(self):
        """Test the method APIExtension.get_extension_info().

        Invoke the method with the name of the service created in setup, but an
        invalid namespace.

        This test passes if the an empty dictionary is returned by the method.
        """
        api_extension = APIExtension(TestApiExtension._client)
        try:
            api_extension.get_extension_info(
                name=TestApiExtension._service_name,
                namespace=TestApiExtension._non_existent_service_namespace)
            self.fail('Should not be able to fetch service ' +
                      TestApiExtension._non_existent_service_name)
        except MissingRecordException:
            pass
Пример #8
0
    def test_0050_get_service_info_with_invalid_namespace(self):
        """Test the method APIExtension.get_extension_info().

        Invoke the method with the name of the service created in setup, but an
        invalid namespace.

        This test passes if the an empty dictionary is returned by the method.
        """
        api_extension = APIExtension(TestApiExtension._client)
        try:
            api_extension.get_extension_info(
                name=TestApiExtension._service_name,
                namespace=TestApiExtension._non_existent_service_namespace)
            self.fail('Should not be able to fetch service ' +
                      TestApiExtension._non_existent_service_name)
        except MissingRecordException as e:
            pass
Пример #9
0
    def test_0040_get_service_info_with_no_namespace(self):
        """Test the method APIExtension.get_extension_info().

        Invoke the method with the name of the first service created in setup,
        but don't send the namespace.

        This test passes if the an MultipleRecordsException is raised by the
        method.
        """
        api_extension = APIExtension(TestApiExtension._client)
        try:
            api_extension.get_extension_info(
                name=TestApiExtension._service_name)
            self.fail('Should not be able to fetch service ' +
                      TestApiExtension._service_name +
                      ' with an empty namespace.')
        except MultipleRecordsException:
            pass
Пример #10
0
def get_telemetry_instance_id(vcd_host: str,
                              vcd_username: str,
                              vcd_password: str,
                              verify_ssl: bool,
                              is_mqtt_exchange: bool,
                              logger_debug=NULL_LOGGER,
                              msg_update_callback=NullPrinter()):
    """Get CSE AMQP or MQTT extension id which is used as instance id.

    Any exception is logged as error. No exception is leaked out
    of this method and does not affect the server startup.

    :param str vcd_host:
    :param str vcd_username:
    :param str vcd_password:
    :param bool verify_ssl:
    :param bool is_mqtt_exchange:
    :param logging.logger logger_debug: logger instance to log any error
    in retrieving CSE extension id.
    :param utils.ConsoleMessagePrinter msg_update_callback: Callback object.

    :return instance id to use for sending data to Vmware telemetry server

    :rtype str (unless no instance id found)
    """
    client = None
    try:
        client = Client(vcd_host, verify_ssl_certs=verify_ssl)
        client.set_credentials(
            BasicLoginCredentials(vcd_username, SYSTEM_ORG_NAME, vcd_password))
        if is_mqtt_exchange:
            # Get MQTT extension uuid
            mqtt_ext_manager = MQTTExtensionManager(client)
            ext_info = mqtt_ext_manager.get_extension_info(
                ext_name=CSE_SERVICE_NAME,
                ext_version=MQTT_EXTENSION_VERSION,
                ext_vendor=MQTT_EXTENSION_VENDOR)
            if not ext_info:
                logger_debug.debug("Failed to retrieve telemetry instance id")
                return None
            logger_debug.debug("Retrieved telemetry instance id")
            return mqtt_ext_manager.get_extension_uuid(
                ext_info[MQTTExtKey.EXT_URN_ID])
        else:
            # Get AMQP extension id
            ext = APIExtension(client)
            cse_info = ext.get_extension_info(CSE_SERVICE_NAME,
                                              namespace=CSE_SERVICE_NAMESPACE)
            logger_debug.debug("Retrieved telemetry instance id")
            return cse_info.get('id')
    except Exception as err:
        msg = f"Cannot retrieve telemetry instance id:{err}"
        msg_update_callback.general(msg)
        logger_debug.error(msg, exc_info=True)
    finally:
        if client is not None:
            client.logout()
Пример #11
0
    def test_0040_get_service_info_with_no_namespace(self):
        """Test the method APIExtension.get_extension_info().

        Invoke the method with the name of the first service created in setup,
        but don't send the namespace.

        This test passes if the an MultipleRecordsException is raised by the
        method.
        """
        api_extension = APIExtension(TestApiExtension._client)
        try:
            api_extension.get_extension_info(
                name=TestApiExtension._service_name)
            self.fail('Should not be able to fetch service ' +
                      TestApiExtension._service_name +
                      ' with an empty namespace.')
        except MultipleRecordsException as e:
            pass
Пример #12
0
 def test_0002_get_extension(self):
     extension = APIExtension(self.client)
     ext_info = extension.get_extension_info(
         self.config['vcd']['extension_name'],
         self.config['vcd']['extension_namespace'])
     assert ext_info
     assert ext_info['name'] == self.config['vcd']['extension_name']
     assert ext_info['namespace'] == \
         self.config['vcd']['extension_namespace']
     assert ext_info['filter_1'].startswith('/api/')
Пример #13
0
 def test_0002_get_extension(self):
     extension = APIExtension(self.client)
     ext_info = extension.get_extension_info(
         self.config['vcd']['extension_name'],
         self.config['vcd']['extension_namespace'])
     assert ext_info
     assert ext_info['name'] == self.config['vcd']['extension_name']
     assert ext_info['namespace'] == \
         self.config['vcd']['extension_namespace']
     assert ext_info['filter_1'].startswith('/api/')
Пример #14
0
 def initialize_on_vcloud(self):
     """Check and/register the extension on vCloud.
     """
     self.log('info', 'Checking the initialization status of extension in vCloud.')
     if not (
         self.conf('vcloud.api_extension.namespace') and
         self.conf('vcloud.api_extension.exchange') and
         self.conf('vcloud.api_extension.routing_key')
     ):
         self.log('warning', 'Missing items in configuration to make the initialization check-up. Ignoring.')
         return
     client = login_as_system_admin()
     ext_manager = APIExtension(client)
     try:
         current_ext_on_vcd = ext_manager.get_extension_info(
             self.name,
             namespace=self.conf('vcloud.api_extension.namespace'))
         self.log('info', 'Extension is already registered on vCloud')
     except MissingRecordException:
         self.log('warning', "This extension is not (yet) declared on vCloud.")
         current_ext_on_vcd = None
     except MultipleRecordsException:
         self.log('error', "Multiple extensions found with same name and namespace")
         sys.exit(-1)
     # Force a fresh redeploy of the full extension (Warning: be carrefull, ID will change !)
     if current_ext_on_vcd and self.conf('vcloud.api_extension.force_redeploy', False):
         ext_manager.delete_extension(
             self.name,
             namespace=self.conf('vcloud.api_extension.namespace'))
         self.log('info', 'Extension is unregistered on vCloud')
         current_ext_on_vcd = None
     # Only update an existing extension (Warning: does not update the API filters/patterns!)
     if current_ext_on_vcd and self.conf('vcloud.api_extension.auto_update', False):
         current_ext_on_vcd = ext_manager.update_extension(
             self.name,
             namespace=self.conf('vcloud.api_extension.namespace'),
             routing_key=self.conf('vcloud.api_extension.routing_key'),
             exchange=self.conf('vcloud.api_extension.exchange'))
         self.log('info', 'Extension is updated on vCloud')
     # Register a new extension
     if not current_ext_on_vcd:
         ext_manager.add_extension(
             self.name,
             namespace=self.conf('vcloud.api_extension.namespace'),
             routing_key=self.conf('vcloud.api_extension.routing_key'),
             exchange=self.conf('vcloud.api_extension.exchange'),
             patterns=self.conf('vcloud.api_extension.api_filters'))
         self.log('info', 'Extension is registered on vCloud')
     # Ensure to enable it
     ext_manager.enable_extension(self.name,
             namespace=self.conf('vcloud.api_extension.namespace'),
             enabled=True)
     self.log('info', 'Extension is enabled on vCloud')
Пример #15
0
def _register_cse(client,
                  routing_key,
                  exchange,
                  msg_update_callback=utils.NullPrinter()):
    """Register or update CSE on vCD.

    :param pyvcloud.vcd.client.Client client:
    :param pyvcloud.vcd.client.Client client:
    :param str routing_key:
    :param str exchange:
    :param utils.ConsoleMessagePrinter msg_update_callback: Callback object.
    """
    ext = APIExtension(client)
    patterns = [
        f'/api/{server_constants.CSE_SERVICE_NAME}',
        f'/api/{server_constants.CSE_SERVICE_NAME}/.*',
        f'/api/{server_constants.CSE_SERVICE_NAME}/.*/.*',
        f'/api/{server_constants.PKS_SERVICE_NAME}',
        f'/api/{server_constants.PKS_SERVICE_NAME}/.*',
        f'/api/{server_constants.PKS_SERVICE_NAME}/.*/.*'
    ]

    cse_info = None
    try:
        cse_info = ext.get_extension_info(
            server_constants.CSE_SERVICE_NAME,
            namespace=server_constants.CSE_SERVICE_NAMESPACE)  # noqa: E501
    except MissingRecordException:
        pass

    if cse_info is None:
        ext.add_extension(
            server_constants.CSE_SERVICE_NAME,
            server_constants.CSE_SERVICE_NAMESPACE,
            routing_key,  # noqa: E501
            exchange,
            patterns)
        msg = f"Registered {server_constants.CSE_SERVICE_NAME} as an API extension in vCD"  # noqa: E501
    else:
        ext.update_extension(
            server_constants.CSE_SERVICE_NAME,
            namespace=server_constants.CSE_SERVICE_NAMESPACE,  # noqa: E501
            routing_key=routing_key,
            exchange=exchange)
        msg = f"Updated {server_constants.CSE_SERVICE_NAME} API Extension in vCD"  # noqa: E501

    msg_update_callback.general(msg)
    INSTALL_LOGGER.info(msg)
def get_telemetry_instance_id(config_dict, logger_debug=NULL_LOGGER,
                              msg_update_callback=NullPrinter()):
    """Get CSE AMQP or MQTT extension id which is used as instance id.

    Any exception is logged as error. No exception is leaked out
    of this method and does not affect the server startup.

    :param dict config_dict: CSE configuration
    :param logging.logger logger_debug: logger instance to log any error
    in retrieving CSE extension id.
    :param utils.ConsoleMessagePrinter msg_update_callback: Callback object.

    :return instance id to use for sending data to Vmware telemetry server

    :rtype str (unless no instance id found)
    """
    vcd = config_dict['vcd']
    try:
        client = Client(vcd['host'], api_version=vcd['api_version'],
                        verify_ssl_certs=vcd['verify'])
        client.set_credentials(BasicLoginCredentials(
            vcd['username'], SYSTEM_ORG_NAME, vcd['password']))
        if should_use_mqtt_protocol(config_dict):
            # Get MQTT extension uuid
            mqtt_ext_manager = MQTTExtensionManager(client)
            ext_info = mqtt_ext_manager.get_extension_info(
                ext_name=CSE_SERVICE_NAME,
                ext_version=MQTT_EXTENSION_VERSION,
                ext_vendor=MQTT_EXTENSION_VENDOR)
            if not ext_info:
                return None
            return mqtt_ext_manager.get_extension_uuid(
                ext_info[MQTTExtKey.EXT_URN_ID])
        else:
            # Get AMQP extension id
            ext = APIExtension(client)
            cse_info = ext.get_extension_info(CSE_SERVICE_NAME,
                                              namespace=CSE_SERVICE_NAMESPACE)
            logger_debug.info("Retrieved telemetry instance id")
            return cse_info.get('id')
    except Exception as err:
        msg = f"Cannot retrieve telemetry instance id:{err}"
        msg_update_callback.general(msg)
        logger_debug.error(msg)
    finally:
        if client is not None:
            client.logout()
Пример #17
0
    def test_0020_get_service_info(self):
        """Test the method APIExtension.get_extension_info().

        Invoke the method with the name and namespace of the first service
        created in setup. A call to APIExtension.get_extension_info() also
        tests APIExtension.get_extension() and APIExtension.get_api_filters().

        This test passes if the service detail retrieved by the method is
        not None, and the details are correct.
        """
        api_extension = APIExtension(TestApiExtension._client)
        service = api_extension.get_extension_info(
            name=TestApiExtension._service_name,
            namespace=TestApiExtension._service1_namespace)
        self._check_service_details(service,
                                    TestApiExtension._service1_namespace)
        self._check_filter_details(service)
Пример #18
0
    def test_0020_get_service_info(self):
        """Test the method APIExtension.get_extension_info().

        Invoke the method with the name and namespace of the first service
        created in setup. A call to APIExtension.get_extension_info() also
        tests APIExtension.get_extension() and APIExtension.get_api_filters().

        This test passes if the service detail retrieved by the method is
        not None, and the details are correct.
        """
        api_extension = APIExtension(TestApiExtension._client)
        service = api_extension.get_extension_info(
            name=TestApiExtension._service_name,
            namespace=TestApiExtension._service1_namespace)
        self._check_service_details(service,
                                    TestApiExtension._service1_namespace)
        self._check_filter_details(service)
Пример #19
0
def get_telemetry_instance_id(vcd,
                              logger_instance=None,
                              msg_update_callback=None):
    """Get CSE extension id which is used as instance id.

    Any exception is logged as error. No exception is leaked out
    of this method and does not affect the server startup.

    :param dict vcd: 'vcd' section of config file as a dict.
    :param logging.logger logger_instance: logger instance to log any error
    in retrieving CSE extension id.
    :param utils.ConsoleMessagePrinter msg_update_callback: Callback object
    that writes messages onto console.

    :return instance id to use for sending data to Vmware telemetry server

    :rtype str

    :raises Exception: if any exception happens while retrieving CSE
    extension id
    """
    try:
        client = Client(vcd['host'],
                        api_version=vcd['api_version'],
                        verify_ssl_certs=vcd['verify'])
        client.set_credentials(
            BasicLoginCredentials(vcd['username'], SYSTEM_ORG_NAME,
                                  vcd['password']))
        ext = APIExtension(client)
        cse_info = ext.get_extension_info(CSE_SERVICE_NAME,
                                          namespace=CSE_SERVICE_NAMESPACE)
        if logger_instance:
            logger_instance.info("Retrieved telemetry instance id")
        return cse_info.get('id')
    except Exception as err:
        msg = f"Cannot retrieve telemetry instance id:{err}"
        if msg_update_callback:
            msg_update_callback.general(msg)
        if logger_instance:
            logger_instance.error(msg)
    finally:
        if client is not None:
            client.logout()
Пример #20
0
def register_extension(ctx, client, config, ext_install):
    if ext_install == 'skip':
        click.secho('Extension configuration: skipped')
        return
    ext = APIExtension(client)
    try:
        name = 'cse'
        cse_ext = ext.get_extension_info(name)
        click.secho('Find extension \'%s\', enabled=%s: %s' %
                    (name, cse_ext['enabled'], bool_to_msg(True)))
    except Exception:
        if ext_install == 'prompt':
            if not click.confirm('Do you want to register CSE as an API '
                                 'extension in vCD?'):
                click.secho('CSE not registered')
                return
        exchange = 'vcdext'
        patterns = '/api/cse,/api/cse/.*,/api/cse/.*/.*'
        ext.add_extension(name, name, name, exchange, patterns.split(','))
        click.secho('Registered extension \'%s\': %s' %
                    (name, bool_to_msg(True)))
def _register_cse(client, routing_key, exchange, msg_update_callback=None):
    """Register or update CSE on vCD.

    :param pyvcloud.vcd.client.Client client:
    :param pyvcloud.vcd.client.Client client:
    :param str routing_key:
    :param str exchange:
    :param utils.ConsoleMessagePrinter msg_update_callback: Callback object
        that writes messages onto console.
    """
    ext = APIExtension(client)
    patterns = [
        f'/api/{CSE_SERVICE_NAME}', f'/api/{CSE_SERVICE_NAME}/.*',
        f'/api/{CSE_SERVICE_NAME}/.*/.*'
    ]

    cse_info = None
    try:
        cse_info = ext.get_extension_info(CSE_SERVICE_NAME,
                                          namespace=CSE_SERVICE_NAMESPACE)
    except MissingRecordException:
        pass

    if cse_info is None:
        ext.add_extension(CSE_SERVICE_NAME, CSE_SERVICE_NAMESPACE, routing_key,
                          exchange, patterns)
        msg = f"Registered {CSE_SERVICE_NAME} as an API extension in vCD"
    else:
        ext.update_extension(CSE_SERVICE_NAME,
                             namespace=CSE_SERVICE_NAMESPACE,
                             routing_key=routing_key,
                             exchange=exchange)
        msg = f"Updated {CSE_SERVICE_NAME} API Extension in vCD"

    if msg_update_callback:
        msg_update_callback.general(msg)
    LOGGER.info(msg)