Beispiel #1
0
def _get_channel_definition(config):
    # type: (IBMMQConfig) -> pymqi.CD
    cd = pymqi.CD()
    cd.ChannelName = pymqi.ensure_bytes(config.channel)
    cd.ConnectionName = pymqi.ensure_bytes(config.connection_name)
    cd.ChannelType = pymqi.CMQC.MQCHT_CLNTCONN
    cd.TransportType = pymqi.CMQC.MQXPT_TCP
    cd.Version = config.mqcd_version
    return cd
Beispiel #2
0
def get_ssl_connection(config):
    # type: (IBMMQConfig) -> pymqi.QueueManager
    """
    Get the connection with SSL
    """
    cd = _get_channel_definition(config)
    cd.SSLCipherSpec = pymqi.ensure_bytes(config.ssl_cipher_spec)

    sco = pymqi.SCO()
    sco.KeyRepository = pymqi.ensure_bytes(config.ssl_key_repository_location)

    queue_manager = pymqi.QueueManager(None)
    queue_manager.connect_with_options(config.queue_manager_name, cd, sco)

    return queue_manager
Beispiel #3
0
    def get_pcf_channel_metrics(self, queue_manager):
        args = {pymqi.CMQCFC.MQCACH_CHANNEL_NAME: pymqi.ensure_bytes('*')}
        try:
            pcf = pymqi.PCFExecute(queue_manager,
                                   convert=self.config.convert_endianness)
            response = pcf.MQCMD_INQUIRE_CHANNEL(args)
        except pymqi.MQMIError as e:
            self.log.warning("Error getting CHANNEL stats %s", e)
        else:
            channels = len(response)
            mname = '{}.channel.channels'.format(metrics.METRIC_PREFIX)
            self.gauge(mname, channels, tags=self.config.tags_no_channel)

            for channel_info in response:
                channel_name = to_string(
                    channel_info[pymqi.CMQCFC.MQCACH_CHANNEL_NAME]).strip()
                channel_tags = self.config.tags_no_channel + [
                    "channel:{}".format(channel_name)
                ]

                self._submit_metrics_from_properties(channel_info,
                                                     metrics.channel_metrics(),
                                                     channel_tags)

        # Check specific channels
        # If a channel is not discoverable, a user may want to check it specifically.
        # Specific channels are checked first to send channel metrics and `ibm_mq.channel` service checks
        # at the same time, but the end result is the same in any order.
        for channel in self.config.channels:
            self._submit_channel_status(queue_manager, channel,
                                        self.config.tags_no_channel)

        # Grab all the discoverable channels
        self._submit_channel_status(queue_manager, '*',
                                    self.config.tags_no_channel)
Beispiel #4
0
 def queue_stats(self, queue_manager, queue_name, tags):
     """
     Grab stats from queues
     """
     pcf = None
     try:
         args = {pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(queue_name), pymqi.CMQC.MQIA_Q_TYPE: pymqi.CMQC.MQQT_ALL}
         pcf = pymqi.PCFExecute(
             queue_manager, response_wait_interval=self.config.timeout, convert=self.config.convert_endianness
         )
         response = pcf.MQCMD_INQUIRE_Q(args)
     except pymqi.MQMIError as e:
         # Don't warn if no messages, see:
         # https://github.com/dsuch/pymqi/blob/v1.12.0/docs/examples.rst#how-to-wait-for-multiple-messages
         if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_NO_MSG_AVAILABLE:
             self.log.debug("No stat messages available for queue %s", queue_name)
         else:
             self.warning("Error getting queue stats for %s: %s", queue_name, e)
     else:
         # Response is a list. It likely has only one member in it.
         for queue_info in response:
             self._submit_queue_stats(queue_info, queue_name, tags)
     finally:
         if pcf is not None:
             pcf.disconnect()
Beispiel #5
0
    def get_pcf_queue_status_metrics(self, queue_manager, queue_name, tags):
        try:
            args = {
                pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(queue_name),
                pymqi.CMQC.MQIA_Q_TYPE: pymqi.CMQC.MQQT_ALL,
                pymqi.CMQCFC.MQIACF_Q_STATUS_ATTRS: pymqi.CMQCFC.MQIACF_ALL,
            }
            pcf = pymqi.PCFExecute(queue_manager, convert=self.config.convert_endianness)
            response = pcf.MQCMD_INQUIRE_Q_STATUS(args)
        except pymqi.MQMIError as e:
            # Don't warn if no messages, see:
            # https://github.com/dsuch/pymqi/blob/v1.12.0/docs/examples.rst#how-to-wait-for-multiple-messages
            if not (e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_NO_MSG_AVAILABLE):
                self.warning("Error getting pcf queue stats for %s: %s", queue_name, e)
        else:
            # Response is a list. It likely has only one member in it.
            for queue_info in response:
                for mname, values in iteritems(metrics.pcf_metrics()):
                    failure_value = values['failure']
                    pymqi_value = values['pymqi_value']
                    mname = '{}.queue.{}'.format(metrics.METRIC_PREFIX, mname)
                    m = int(queue_info[pymqi_value])

                    if m > failure_value:
                        self.send_metric(GAUGE, mname, m, tags=tags)
                    else:
                        msg = "Unable to get {}, turn on queue level monitoring to access these metrics for {}"
                        msg = msg.format(mname, queue_name)
                        self.log.debug(msg)
Beispiel #6
0
    def test_connection_with_tls(self):
        """Test connection to QueueManager with TLS."""
        qmgr = pymqi.QueueManager(None)
        conn_info = pymqi.ensure_bytes('{0}({1})'.format(self.host, self.port))

        cd = pymqi.CD(
            Version=pymqi.CMQXC.MQCD_VERSION_7,  # pylint: disable=C0103
            ChannelName=self.tls_channel_name,
            ConnectionName=conn_info,
            SSLCipherSpec=self.cypher_spec)

        sco = pymqi.SCO(Version=pymqi.CMQC.MQSCO_VERSION_5,
                        KeyRepository=os.path.join(
                            self.key_repo_location_client,
                            self.certificate_label_client),
                        CertificateLabel=self.certificate_label_client)

        opts = pymqi.CMQC.MQCNO_HANDLE_SHARE_NO_BLOCK

        qmgr.connectWithOptions(self.queue_manager,
                                cd,
                                sco,
                                opts=opts,
                                user=self.user,
                                password=self.password)
        is_connected = qmgr.is_connected
        if is_connected:
            qmgr.disconnect()

        self.assertTrue(is_connected)
    def get_pcf_queue_status_metrics(self, queue_manager, queue_name, tags):
        try:
            args = {
                pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(queue_name),
                pymqi.CMQC.MQIA_Q_TYPE: pymqi.CMQC.MQQT_ALL,
                pymqi.CMQCFC.MQIACF_Q_STATUS_ATTRS: pymqi.CMQCFC.MQIACF_ALL,
            }
            pcf = pymqi.PCFExecute(queue_manager)
            response = pcf.MQCMD_INQUIRE_Q_STATUS(args)
        except pymqi.MQMIError as e:
            self.warning("Error getting pcf queue stats for %s: %s",
                         queue_name, e)
        else:
            # Response is a list. It likely has only one member in it.
            for queue_info in response:
                for mname, values in iteritems(metrics.pcf_metrics()):
                    failure_value = values['failure']
                    pymqi_value = values['pymqi_value']
                    mname = '{}.queue.{}'.format(metrics.METRIC_PREFIX, mname)
                    m = int(queue_info[pymqi_value])

                    if m > failure_value:
                        self.send_metric(GAUGE, mname, m, tags=tags)
                    else:
                        msg = "Unable to get {}, turn on queue level monitoring to access these metrics for {}"
                        msg = msg.format(mname, queue_name)
                        self.log.debug(msg)
    def _submit_channel_status(self, queue_manager, search_channel_name, tags, channels_to_skip=None):
        """Submit channel status

        Note: Error 3065 (MQRCCF_CHL_STATUS_NOT_FOUND) might indicate that the channel has not been used.
        More info: https://www.ibm.com/support/knowledgecenter/SSFKSJ_7.1.0/com.ibm.mq.doc/fm16690_.htm

        :param search_channel_name might contain wildcard characters
        """
        channels_to_skip = channels_to_skip or []
        search_channel_tags = tags + ["channel:{}".format(search_channel_name)]
        pcf = None
        try:
            args = {pymqi.CMQCFC.MQCACH_CHANNEL_NAME: pymqi.ensure_bytes(search_channel_name)}
            pcf = pymqi.PCFExecute(
                queue_manager, response_wait_interval=self.config.timeout, convert=self.config.convert_endianness
            )
            response = pcf.MQCMD_INQUIRE_CHANNEL_STATUS(args)
            self.service_check(
                self.CHANNEL_SERVICE_CHECK, AgentCheck.OK, search_channel_tags, hostname=self.config.hostname
            )
        except pymqi.MQMIError as e:
            if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQCFC.MQRCCF_CHL_STATUS_NOT_FOUND:
                self.service_check(
                    self.CHANNEL_SERVICE_CHECK, AgentCheck.CRITICAL, search_channel_tags, hostname=self.config.hostname
                )
                self.log.debug("Channel status not found for channel %s: %s", search_channel_name, e)
            elif e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_NO_MSG_AVAILABLE:
                self.service_check(
                    self.CHANNEL_SERVICE_CHECK, AgentCheck.UNKNOWN, search_channel_tags, hostname=self.config.hostname
                )
                self.log.debug("There are no messages available for channel %s", search_channel_name)
            else:
                self.service_check(
                    self.CHANNEL_SERVICE_CHECK, AgentCheck.CRITICAL, search_channel_tags, hostname=self.config.hostname
                )
                self.log.warning("Error getting CHANNEL status for channel %s: %s", search_channel_name, e)
        else:
            for channel_info in response:
                channel_name = to_string(channel_info[pymqi.CMQCFC.MQCACH_CHANNEL_NAME]).strip()
                if channel_name in channels_to_skip:
                    continue
                channel_tags = tags + ["channel:{}".format(channel_name)]

                self._submit_metrics_from_properties(
                    channel_info, channel_name, metrics.channel_status_metrics(), channel_tags
                )

                channel_status = channel_info[pymqi.CMQCFC.MQIACH_CHANNEL_STATUS]
                self._submit_channel_count(channel_name, channel_status, channel_tags)
                self._submit_status_check(channel_name, channel_status, channel_tags)
        finally:
            if pcf is not None:
                pcf.disconnect()
Beispiel #9
0
    def get_pcf_queue_status_metrics(self, queue_manager, queue_name, tags):
        pcf = None
        try:
            args = {
                pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(queue_name),
                pymqi.CMQC.MQIA_Q_TYPE: pymqi.CMQC.MQQT_ALL,
                pymqi.CMQCFC.MQIACF_Q_STATUS_ATTRS: pymqi.CMQCFC.MQIACF_ALL,
            }
            pcf = pymqi.PCFExecute(
                queue_manager, response_wait_interval=self.config.timeout, convert=self.config.convert_endianness
            )
            response = pcf.MQCMD_INQUIRE_Q_STATUS(args)
        except pymqi.MQMIError as e:
            # Don't warn if no messages, see:
            # https://github.com/dsuch/pymqi/blob/v1.12.0/docs/examples.rst#how-to-wait-for-multiple-messages
            if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_NO_MSG_AVAILABLE:
                self.log.debug("No PCF queue status messages available for queue %s", queue_name)
            else:
                self.warning("Error getting pcf queue status for %s: %s", queue_name, e)
        else:
            # Response is a list. It likely has only one member in it.
            for queue_info in response:
                for mname, values in iteritems(metrics.pcf_metrics()):
                    metric_name = '{}.queue.{}'.format(metrics.METRIC_PREFIX, mname)
                    try:
                        if callable(values):
                            metric_value = values(self.config.qm_timezone, queue_info)
                            if metric_value is not None:
                                self.send_metric(GAUGE, metric_name, metric_value, tags=tags)
                            else:
                                msg = """
                                    Unable to get %s. Turn on queue level monitoring to access these metrics for %s.
                                    Check `DISPLAY QSTATUS(%s) MONITOR`.
                                    """
                                self.log.debug(msg, metric_name, queue_name, queue_name)
                        else:
                            failure_value = values['failure']
                            pymqi_value = values['pymqi_value']
                            metric_value = int(queue_info.get(pymqi_value, None))

                            if metric_value > failure_value:
                                self.send_metric(GAUGE, metric_name, metric_value, tags=tags)
                            else:
                                msg = "Unable to get {}, turn on queue level monitoring to access these metrics for {}"
                                msg = msg.format(metric_name, queue_name)
                                self.log.debug(msg)
                    except Exception as e:
                        msg = "Unable to get metric {} from queue {}. Error is {}.".format(metric_name, queue_name, e)
                        self.log.warning(msg)
        finally:
            if pcf is not None:
                pcf.disconnect()
Beispiel #10
0
 def get_pcf_queue_reset_metrics(self, queue_manager, queue_name, tags):
     try:
         args = {pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(queue_name)}
         pcf = pymqi.PCFExecute(queue_manager, convert=self.config.convert_endianness)
         response = pcf.MQCMD_RESET_Q_STATS(args)
     except pymqi.MQMIError as e:
         self.warning("Error getting pcf queue stats for %s: %s", queue_name, e)
     else:
         # Response is a list. It likely has only one member in it.
         for queue_info in response:
             metrics_map = metrics.pcf_status_reset_metrics()
             prefix = "{}.queue".format(metrics.METRIC_PREFIX)
             self.send_metrics_from_properties(queue_info, metrics_map, prefix, tags)
Beispiel #11
0
 def queue_stats(self, queue_manager, queue_name, tags):
     """
     Grab stats from queues
     """
     try:
         args = {pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(queue_name), pymqi.CMQC.MQIA_Q_TYPE: pymqi.CMQC.MQQT_ALL}
         pcf = pymqi.PCFExecute(queue_manager, convert=self.config.convert_endianness)
         response = pcf.MQCMD_INQUIRE_Q(args)
     except pymqi.MQMIError as e:
         self.warning("Error getting queue stats for %s: %s", queue_name, e)
     else:
         # Response is a list. It likely has only one member in it.
         for queue_info in response:
             self._submit_queue_stats(queue_info, queue_name, tags)
Beispiel #12
0
def get_ssl_connection(config):
    # type: (IBMMQConfig) -> pymqi.QueueManager
    """
    Get the connection with SSL
    """
    cd = _get_channel_definition(config)
    cd.SSLCipherSpec = pymqi.ensure_bytes(config.ssl_cipher_spec)

    sco = pymqi.SCO()
    sco.KeyRepository = pymqi.ensure_bytes(config.ssl_key_repository_location)

    if config.ssl_certificate_label:
        sco.CertificateLabel = pymqi.ensure_bytes(config.ssl_certificate_label)

    connect_options = {}
    if config.username and config.password:
        connect_options.update({
            'user': config.username,
            'password': config.password,
        })

    log.debug(
        "Create SSL connection with ConnectionName=%s, ChannelName=%s, Version=%s, SSLCipherSpec=%s, "
        "KeyRepository=%s, CertificateLabel=%s, user=%s",
        cd.ConnectionName,
        cd.ChannelName,
        cd.Version,
        cd.SSLCipherSpec,
        sco.KeyRepository,
        sco.CertificateLabel,
        connect_options.get('user'),
    )
    queue_manager = pymqi.QueueManager(None)
    queue_manager.connect_with_options(config.queue_manager_name, cd, sco,
                                       **connect_options)
    return queue_manager
Beispiel #13
0
 def get_pcf_queue_reset_metrics(self, queue_manager, queue_name, tags):
     try:
         args = {pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(queue_name)}
         pcf = pymqi.PCFExecute(queue_manager, convert=self.config.convert_endianness)
         response = pcf.MQCMD_RESET_Q_STATS(args)
     except pymqi.MQMIError as e:
         # Don't warn if no messages, see:
         # https://github.com/dsuch/pymqi/blob/v1.12.0/docs/examples.rst#how-to-wait-for-multiple-messages
         if not (e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_NO_MSG_AVAILABLE):
             self.warning("Error getting pcf queue stats for %s: %s", queue_name, e)
     else:
         # Response is a list. It likely has only one member in it.
         for queue_info in response:
             metrics_map = metrics.pcf_status_reset_metrics()
             prefix = "{}.queue".format(metrics.METRIC_PREFIX)
             self.send_metrics_from_properties(queue_info, metrics_map, prefix, tags)
Beispiel #14
0
    def _discover_queues(self, queue_manager, mq_pattern_filter):
        queues = []

        for queue_type in SUPPORTED_QUEUE_TYPES:
            args = {pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(mq_pattern_filter), pymqi.CMQC.MQIA_Q_TYPE: queue_type}
            try:
                pcf = pymqi.PCFExecute(queue_manager, convert=self.config.convert_endianness)
                response = pcf.MQCMD_INQUIRE_Q(args)
            except pymqi.MQMIError as e:
                self.warning("Error discovering queue: %s", e)
            else:
                for queue_info in response:
                    queue = queue_info[pymqi.CMQC.MQCA_Q_NAME]
                    queues.append(to_string(queue).strip())

        return queues
 def get_pcf_queue_reset_metrics(self, queue_manager, queue_name, tags):
     try:
         args = {pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(queue_name)}
         pcf = pymqi.PCFExecute(queue_manager)
         response = pcf.MQCMD_RESET_Q_STATS(args)
     except pymqi.MQMIError as e:
         self.warning("Error getting pcf queue stats for %s: %s",
                      queue_name, e)
     else:
         # Response is a list. It likely has only one member in it.
         for queue_info in response:
             for metric_name, (pymqi_type, metric_type) in iteritems(
                     metrics.pcf_status_reset_metrics()):
                 metric_full_name = '{}.queue.{}'.format(
                     metrics.METRIC_PREFIX, metric_name)
                 metric_value = int(queue_info[pymqi_type])
                 self.send_metric(metric_type, metric_full_name,
                                  metric_value, tags)
Beispiel #16
0
    def _discover_queues(self, queue_manager, mq_pattern_filter):
        queues = []

        for queue_type in SUPPORTED_QUEUE_TYPES:
            args = {pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(mq_pattern_filter), pymqi.CMQC.MQIA_Q_TYPE: queue_type}
            try:
                pcf = pymqi.PCFExecute(queue_manager, convert=self.config.convert_endianness)
                response = pcf.MQCMD_INQUIRE_Q(args)
            except pymqi.MQMIError as e:
                # Don't warn if no messages, see:
                # https://github.com/dsuch/pymqi/blob/v1.12.0/docs/examples.rst#how-to-wait-for-multiple-messages
                if not (e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_NO_MSG_AVAILABLE):
                    self.warning("Error discovering queue: %s", e)
            else:
                for queue_info in response:
                    queue = queue_info[pymqi.CMQC.MQCA_Q_NAME]
                    queues.append(to_string(queue).strip())

        return queues
Beispiel #17
0
    def _discover_queues(self, queue_manager, mq_pattern_filter):
        # type: (pymqi.QueueManager, str) -> List[str]
        queues = []

        for queue_type in SUPPORTED_QUEUE_TYPES:
            args = {pymqi.CMQC.MQCA_Q_NAME: pymqi.ensure_bytes(mq_pattern_filter), pymqi.CMQC.MQIA_Q_TYPE: queue_type}
            pcf = None
            try:
                pcf = pymqi.PCFExecute(
                    queue_manager, response_wait_interval=self.config.timeout, convert=self.config.convert_endianness
                )
                response = pcf.MQCMD_INQUIRE_Q(args)
            except pymqi.MQMIError as e:
                # Don't warn if no messages, see:
                # https://github.com/dsuch/pymqi/blob/v1.12.0/docs/examples.rst#how-to-wait-for-multiple-messages
                if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_NO_MSG_AVAILABLE:
                    self.log.debug("No queue info available")
                elif e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_UNKNOWN_OBJECT_NAME:
                    self.log.debug("No matching queue of type %d for pattern %s", queue_type, mq_pattern_filter)
                else:
                    self.warning("Error discovering queue: %s", e)
            else:
                for queue_info in response:
                    queue = queue_info.get(pymqi.CMQC.MQCA_Q_NAME, None)
                    if queue:
                        queue_name = to_string(queue).strip()
                        self.log.debug("Discovered queue: %s", queue_name)
                        queues.append(queue_name)
                    else:
                        self.log.debug('Discovered queue with empty name, skipping.')
                        continue
                self.log.debug("%s queues discovered", str(len(queues)))
            finally:
                # Close internal reply queue to prevent filling up a dead-letter queue.
                # https://github.com/dsuch/pymqi/blob/084ab0b2638f9d27303a2844badc76635c4ad6de/code/pymqi/__init__.py#L2892-L2902
                # https://dsuch.github.io/pymqi/examples.html#how-to-specify-dynamic-reply-to-queues
                if pcf is not None:
                    pcf.disconnect()

        if not queues:
            self.warning("No matching queue of type MQQT_LOCAL or MQQT_REMOTE for pattern %s", mq_pattern_filter)

        return queues
 def _discover_channels(self, queue_manager):
     """Discover all channels"""
     args = {pymqi.CMQCFC.MQCACH_CHANNEL_NAME: pymqi.ensure_bytes('*')}
     pcf = None
     response = None
     try:
         pcf = pymqi.PCFExecute(
             queue_manager, response_wait_interval=self.config.timeout, convert=self.config.convert_endianness
         )
         response = pcf.MQCMD_INQUIRE_CHANNEL(args)
     except pymqi.MQMIError as e:
         # Don't warn if no messages, see:
         # https://github.com/dsuch/pymqi/blob/v1.12.0/docs/examples.rst#how-to-wait-for-multiple-messages
         if e.comp == pymqi.CMQC.MQCC_FAILED and e.reason == pymqi.CMQC.MQRC_NO_MSG_AVAILABLE:
             self.log.debug("There are no messages available for PCF channel")
         else:
             self.log.warning("Error getting CHANNEL stats %s", e)
     finally:
         if pcf is not None:
             pcf.disconnect()
     return response
Beispiel #19
0
def prepare_queue_manager():
    import pymqi

    conn_info = '{0}({1})'.format(common.HOST, common.PORT)
    qm_name = common.QUEUE_MANAGER.lower()

    qmgr = pymqi.QueueManager(None)
    qmgr.connectTCPClient(common.QUEUE_MANAGER, pymqi.CD(), common.CHANNEL,
                          conn_info, common.USERNAME, common.PASSWORD)
    pcf = pymqi.PCFExecute(qmgr, response_wait_interval=5000)

    attrs = [
        pymqi.CFST(
            Parameter=pymqi.CMQC.MQCA_SSL_KEY_REPOSITORY,
            String=pymqi.ensure_bytes('/etc/mqm/pki/keys/{}'.format(qm_name)),
        ),
        pymqi.CFST(Parameter=pymqi.CMQC.MQCA_CERT_LABEL,
                   String=pymqi.ensure_bytes(qm_name)),
    ]
    pcf.MQCMD_CHANGE_Q_MGR(attrs)

    tls_channel_name = pymqi.ensure_bytes(common.CHANNEL_SSL)
    cypher_spec = pymqi.ensure_bytes(common.SSL_CYPHER_SPEC)
    client_dn = pymqi.ensure_bytes('CN={}'.format(common.SSL_CLIENT_LABEL))
    certificate_label_qmgr = pymqi.ensure_bytes(qm_name)

    attrs = [
        pymqi.CFST(Parameter=pymqi.CMQCFC.MQCACH_CHANNEL_NAME,
                   String=pymqi.ensure_bytes(tls_channel_name)),
        pymqi.CFIN(Parameter=pymqi.CMQCFC.MQIACH_CHANNEL_TYPE,
                   Value=pymqi.CMQC.MQCHT_SVRCONN),
        pymqi.CFST(Parameter=pymqi.CMQCFC.MQCACH_SSL_CIPHER_SPEC,
                   String=cypher_spec),
        pymqi.CFST(Parameter=pymqi.CMQCFC.MQCACH_SSL_PEER_NAME,
                   String=client_dn),
        pymqi.CFIN(Parameter=pymqi.CMQCFC.MQIACH_SSL_CLIENT_AUTH,
                   Value=pymqi.CMQXC.MQSCA_OPTIONAL),
        pymqi.CFST(Parameter=pymqi.CMQC.MQCA_CERT_LABEL,
                   String=certificate_label_qmgr),
        pymqi.CFIN(Parameter=pymqi.CMQCFC.MQIACF_REPLACE,
                   Value=pymqi.CMQCFC.MQRP_YES),
    ]
    pcf.MQCMD_CREATE_CHANNEL(attrs)

    attrs = [
        pymqi.CFST(Parameter=pymqi.CMQCFC.MQCACH_CHANNEL_NAME,
                   String=pymqi.ensure_bytes(tls_channel_name)),
        pymqi.CFIN(Parameter=pymqi.CMQCFC.MQIACF_CHLAUTH_TYPE,
                   Value=pymqi.CMQCFC.MQCAUT_USERMAP),
        pymqi.CFIN(Parameter=pymqi.CMQCFC.MQIACF_ACTION,
                   Value=pymqi.CMQCFC.MQACT_REPLACE),
        pymqi.CFST(Parameter=pymqi.CMQCFC.MQCACH_CLIENT_USER_ID,
                   String=pymqi.ensure_bytes(common.USERNAME)),
        pymqi.CFIN(Parameter=pymqi.CMQC.MQIA_CHECK_CLIENT_BINDING,
                   Value=pymqi.CMQCFC.MQCHK_REQUIRED_ADMIN),
        pymqi.CFIN(Parameter=pymqi.CMQCFC.MQIACH_USER_SOURCE,
                   Value=pymqi.CMQC.MQUSRC_MAP),
        pymqi.CFST(Parameter=pymqi.CMQCFC.MQCACH_MCA_USER_ID, String=b'mqm'),
    ]
    pcf.MQCMD_SET_CHLAUTH_REC(attrs)

    attrs = [
        pymqi.CFST(Parameter=pymqi.CMQCFC.MQCACH_CHANNEL_NAME,
                   String=pymqi.ensure_bytes(tls_channel_name)),
        pymqi.CFIN(Parameter=pymqi.CMQCFC.MQIACF_CHLAUTH_TYPE,
                   Value=pymqi.CMQCFC.MQCAUT_BLOCKUSER),
        pymqi.CFST(Parameter=pymqi.CMQCFC.MQCACH_MCA_USER_ID_LIST,
                   String=b'nobody'),
        pymqi.CFIN(Parameter=pymqi.CMQCFC.MQIACH_WARNING,
                   Value=pymqi.CMQC.MQWARN_NO),
        pymqi.CFIN(Parameter=pymqi.CMQCFC.MQIACF_ACTION,
                   Value=pymqi.CMQCFC.MQACT_REPLACE),
    ]
    pcf.MQCMD_SET_CHLAUTH_REC(attrs)

    pcf.disconnect()
    qmgr.disconnect()