Exemple #1
0
    def push_certificate(self, pkey, cert):

        icifc = IcontrolInterface(
            device=self.options.device,
            address=self.address,
            username=self.options.admin_username,
            password=self.options.admin_password,
            port=self.options.ssl_port,
            debug=self.options.verbose,
        )
        ic = icifc.open()
        key_pem = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
        cert_pem = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)

        try:
            ic.Management.KeyCertificate.certificate_delete(mode="MANAGEMENT_MODE_WEBSERVER", cert_ids=["server"])
            ic.Management.KeyCertificate.key_delete(mode="MANAGEMENT_MODE_WEBSERVER", key_ids=["server"])
        except:
            LOG.warning("Exception occurred while deleting cert/key")

        ic.Management.KeyCertificate.certificate_import_from_pem(
            mode="MANAGEMENT_MODE_WEBSERVER", cert_ids=["server"], pem_data=[cert_pem], overwrite=1
        )

        ic.Management.KeyCertificate.key_import_from_pem(
            mode="MANAGEMENT_MODE_WEBSERVER", key_ids=["server"], pem_data=[key_pem], overwrite=1
        )

        icifc.close()

        # XXX: Unfortunately we can't reinit httpd through iControl. It's a KI
        # http://devcentral.f5.com/Default.aspx?tabid=53&forumid=1&postid=1170498&view=topic
        #
        # action = pc.System.Services.typefactory.\
        #        create('System.Services.ServiceAction').\
        #        SERVICE_ACTION_REINIT
        # service = pc.System.Services.typefactory.\
        #        create('System.Services.ServiceType').\
        #        SERVICE_HTTPD
        # pc.System.Services.set_service(services = [service], \
        #                               service_action = action)
        # pc.System.Services.get_service_status([service])

        with SSHInterface(
            device=self.options.device,
            address=self.address,
            username=self.options.root_username,
            password=self.options.root_password,
            port=self.options.ssh_port,
        ) as sshifc:
            version = SCMD.ssh.get_version(ifc=sshifc)
            if version >= "bigiq 4.4":
                sshifc.api.run("bigstart reinit webd")
            elif version >= "bigiq 4.3" and version < "bigiq 4.4":
                sshifc.api.run("bigstart reinit nginx")
            else:
                sshifc.api.run("bigstart reinit httpd")

        return True
Exemple #2
0
    def push_certificate(self, pkey, cert):

        icifc = IcontrolInterface(device=self.options.device,
                                  address=self.address,
                                  username=self.options.admin_username,
                                  password=self.options.admin_password,
                                  port=self.options.ssl_port,
                                  debug=self.options.verbose)
        ic = icifc.open()
        key_pem = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
        cert_pem = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)

        try:
            ic.Management.KeyCertificate.certificate_delete(
                mode='MANAGEMENT_MODE_WEBSERVER', cert_ids=['server'])
            ic.Management.KeyCertificate.key_delete(
                mode='MANAGEMENT_MODE_WEBSERVER', key_ids=['server'])
        except:
            LOG.warning('Exception occurred while deleting cert/key')

        ic.Management.KeyCertificate.certificate_import_from_pem(
                mode='MANAGEMENT_MODE_WEBSERVER', cert_ids=['server'],
                pem_data=[cert_pem], overwrite=1)

        ic.Management.KeyCertificate.key_import_from_pem(
                mode='MANAGEMENT_MODE_WEBSERVER', key_ids=['server'],
                pem_data=[key_pem], overwrite=1)

        icifc.close()

        # XXX: Unfortunately we can't reinit httpd through iControl. It's a KI
        # http://devcentral.f5.com/Default.aspx?tabid=53&forumid=1&postid=1170498&view=topic
        #
        # action = pc.System.Services.typefactory.\
        #        create('System.Services.ServiceAction').\
        #        SERVICE_ACTION_REINIT
        # service = pc.System.Services.typefactory.\
        #        create('System.Services.ServiceType').\
        #        SERVICE_HTTPD
        # pc.System.Services.set_service(services = [service], \
        #                               service_action = action)
        # pc.System.Services.get_service_status([service])

        with SSHInterface(device=self.options.device,
                          address=self.address,
                          username=self.options.root_username,
                          password=self.options.root_password,
                          port=self.options.ssh_port) as sshifc:
            version = SCMD.ssh.get_version(ifc=sshifc)
            if version >= 'bigiq 4.4' or version < 'bigiq 4.0' or \
               version >= 'iworkflow 2.0':
                sshifc.api.run('bigstart reinit webd')
            elif version >= 'bigiq 4.3' and version < 'bigiq 4.4':
                sshifc.api.run('bigstart reinit nginx')
            else:  # all BPs
                if version < 'bigip 11.5.0':
                    x = sshifc.api.run('bigstart reinit httpd')
                    LOG.debug("pushcert (res: bigstart reinit httpd): {0}".format(x))
                else:  # See BZ553787 (Matt Davey: restjavad must be restarted after pushing a cert)
                    # was for > 12.0 only but the "fix" made it to all new HFs
                    LOG.debug("pushcert (res: bigstart restart)...(because of issue with restajavad and/or httpd on certain platforms)")
                    # sshifc.api.run('bigstart restart')
                    sshifc.api.run('bigstart restart httpd')
                    self.wait_for_available(version)

        return True
Exemple #3
0
    def by_icontrol(self, filename, hfiso=None):
        iso_version = cm.version_from_metadata(filename)
        timeout = self.options.timeout
        if hfiso:
            hfiso_version = cm.version_from_metadata(hfiso)
        else:
            hfiso_version = None

        LOG.debug('iso: %s', iso_version)

        icifc = IcontrolInterface(address=self.address,
                                  username=self.options.admin_username,
                                  password=self.options.admin_password,
                                  port=self.options.ssl_port)
        ic = icifc.open()
        running_volume = ICMD.software.get_active_volume(ifc=icifc)
        assert running_volume != self.options.volume, \
            "Can't install on the active volume"

        version = ICMD.system.get_version(ifc=icifc)
        base = os.path.basename(filename)

        LOG.debug('running: %s', version)
        essential = self.options.essential_config
        if not essential and abs(iso_version) < abs(version):
            LOG.warning('Enforcing --esential-config')
            essential = True

        LOG.info('Setting the global DB vars...')
        ic.Management.Partition.set_active_partition(active_partition='Common')
        ic.Management.DBVariable.modify(variables=[
            {'name': 'LiveInstall.MoveConfig',
             'value': essential and 'disable' or 'enable'},
            {'name': 'LiveInstall.SaveConfig',
             'value': essential and 'disable' or 'enable'}
        ])
        # =======================================================================
        # Copy the ISO over to the device in /shared/images if it's not already
        # in the software repository.
        # =======================================================================
        images = ICMD.software.get_software_image(ifc=icifc)
        haz_it = any(filter(lambda x: x['verified'] and
                            x['product'] == iso_version.product.to_tmos and
                            x['version'] == iso_version.version and
                            x['build'] == iso_version.build, images))

        volume = self.options.volume or ICMD.software.get_inactive_volume(ifc=icifc)
        LOG.info('Preparing volume %s...', volume)
        ICMD.software.clear_volume(volume=volume, ifc=icifc)

        def is_available(items):
            all_count = len(items)
            return sum(bool(x['verified']) for x in items) == all_count

        is_clustered = ic.System.Cluster.is_clustered_environment()

        LOG.info('Timeout: %d', timeout)

        if essential:
            with SSHInterface(address=self.address,
                              username=self.options.root_username,
                              password=self.options.root_password,
                              timeout=timeout, port=self.options.ssh_port) as sshifc:
                ssh = sshifc.api
                lines = ssh.run('ls ' + SHARED_IMAGES).stdout.split()
                images = [x for x in lines if '.iso' in x]

            hfbase = os.path.basename(hfiso) if hfiso else None
            for image in images:
                if base != image and hfbase != image:
                    # If the image is a hotfix image
                    if 'hotfix' in image.lower():
                        LOG.info('Deleting hotfix image: %s' % image)
                        ICMD.software.delete_software_image(image, is_hf=True,
                                                            ifc=icifc)

                    # Otherwise assume it is a base image
                    else:
                        LOG.info('Deleting base image: %s' % image)
                        ICMD.software.delete_software_image(image, ifc=icifc)

        if not haz_it:
            LOG.info('Importing base iso %s', base)
            SCMD.ssh.scp_put(address=self.address,
                             username=self.options.root_username,
                             password=self.options.root_password,
                             port=self.options.ssh_port,
                             source=filename, nokex=False, timeout=timeout)

            LOG.info('Wait for image to be imported %s', base)
            ICMD.software.GetSoftwareImage(filename=base, ifc=icifc) \
                .run_wait(is_available, timeout=timeout,
                          timeout_message="Timeout ({0}s) while waiting for the software image to be imported.")

        if hfiso:
            images = ICMD.software.get_software_image(ifc=icifc, is_hf=True)
            haz_it = any(filter(lambda x: x['verified'] and
                                x['product'] == hfiso_version.product.to_tmos and
                                x['version'] == hfiso_version.version and
                                x['build'] == hfiso_version.build, images))

            if not haz_it:
                hfbase = os.path.basename(hfiso)
                LOG.info('Importing hotfix iso %s', hfiso)
                SCMD.ssh.scp_put(address=self.address,
                                 username=self.options.root_username,
                                 password=self.options.root_password,
                                 port=self.options.ssh_port,
                                 source=hfiso, nokex=False)

                LOG.info('Wait for image to be imported %s', hfbase)
                ICMD.software.GetSoftwareImage(filename=hfbase, ifc=icifc, is_hf=True) \
                    .run_wait(is_available, timeout_message="Timeout ({0}s) while waiting for the hotfix image to be imported.")

        def is_still_removing(items):
            return not any(filter(lambda x: x['status'].startswith('removing'),
                                  items))

        def is_still_installing(items):
            return not any(filter(lambda x: x['status'].startswith('installing') or
                                  x['status'].startswith('waiting') or
                                  x['status'].startswith('testing') or
                                  x['status'] in ('audited', 'auditing',
                                                  'upgrade needed'),
                                  items))

        volumes = ICMD.software.get_software_status(ifc=icifc)
        assert is_still_installing(volumes), "An install is already in " \
                                             "progress on another slot: %s" % volumes

        ICMD.software.GetSoftwareStatus(volume=volume, ifc=icifc) \
                     .run_wait(is_still_removing,
                               # CAVEAT: tracks progress only for the first blade
                               progress_cb=lambda x: x[0]['status'],
                               timeout=timeout)

        LOG.info('Installing %s...', iso_version)

        ICMD.software.install_software(hfiso_version or iso_version,
                                       volume=volume, ifc=icifc)

        ret = ICMD.software.GetSoftwareStatus(volume=volume, ifc=icifc) \
            .run_wait(is_still_installing,
                      # CAVEAT: tracks progress only for the first blade
                      progress_cb=lambda x: x[0]['status'],
                      timeout=timeout,
                      timeout_message="Timeout ({0}s) while waiting software install to finish.",
                      stabilize=10)

        LOG.info('Resetting the global DB vars...')
        ic.Management.DBVariable.modify(variables=[
            {'name': 'LiveInstall.MoveConfig',
             'value': essential and 'enable' or 'disable'},
            {'name': 'LiveInstall.SaveConfig',
             'value': essential and 'enable' or 'disable'}
        ])

        if sum(x['status'] == 'complete' for x in ret) != len(ret):
            raise InstallFailed('Install did not succeed: %s' % ret)

        LOG.info('Setting the active boot location %s.', volume)
        if is_clustered:
            # ===================================================================
            # Apparently on chassis systems the device is rebooted automatically
            # upon setting the active location, just like `b software desired
            # HD1.N active enable`.
            # ===================================================================
            uptime = ic.System.SystemInfo.get_uptime()
            ic.System.SoftwareManagement.set_cluster_boot_location(location=volume)
            time.sleep(60)
        else:
            ic.System.SoftwareManagement.set_boot_location(location=volume)
            LOG.info('Rebooting...')
            uptime = ICMD.system.reboot(ifc=icifc)

        # Grab a new iControl handle that uses the default admin credentials.
        if essential:
            icifc.close()
            icifc = IcontrolInterface(address=self.address,
                                      port=self.options.ssl_port)
            icifc.open()

        if uptime:
            ICMD.system.HasRebooted(uptime, ifc=icifc).run_wait(timeout=timeout)
            LOG.info('Device is rebooting...')

        LOG.info('Wait for box to be ready...')
        ICMD.system.IsServiceUp('MCPD', ifc=icifc).\
            run_wait(timeout=timeout,
                     timeout_message="Timeout ({0}s) while waiting for MCPD to come up")
        ICMD.system.IsServiceUp('TMM', ifc=icifc).\
            run_wait(timeout_message="Timeout ({0}s) while waiting for TMM to come up")

        ICMD.management.GetDbvar('Configsync.LocalConfigTime', ifc=icifc).\
            run_wait(lambda x: int(x) > 0,
                     progress_cb=lambda x: 'waiting configsync...',
                     timeout=timeout)
        ICMD.system.FileExists('/var/run/mprov.pid', ifc=icifc).\
            run_wait(lambda x: x is False,
                     progress_cb=lambda x: 'mprov still running...',
                     timeout=timeout)
        ICMD.system.FileExists('/var/run/grub.conf.lock', ifc=icifc).\
            run_wait(lambda x: x is False,
                     progress_cb=lambda x: 'grub.lock still present...',
                     timeout=timeout)

        current_version = ICMD.system.get_version(ifc=icifc)
        expected_version = hfiso_version or iso_version
        try:
            if expected_version != current_version:
                raise InstallFailed('Version expected: %s but found %s' %
                                    (expected_version, current_version))
        finally:
            icifc.close()

        # Will use SSH!
        if essential:
            self._initialize_big3d()

        if essential and current_version.product.is_em:
            self._initialize_em()

        self.has_essential_config = essential
Exemple #4
0
class VcmpPlacer(ConfigPlacer):
    SystemConfig = SystemConfig
    vCMPConfig = vCMPConfig

    def __init__(self, guests, *args, **kwargs):
        super(VcmpPlacer, self).__init__(*args, **kwargs)
        # Case when there is no vCMP guests to setup.
        if not guests:
            guests = []

        self.guests = []
        for guest in guests:
            if isinstance(guest, DeviceAccess):
                item = guest
            else:
                if len(guest.split(':')) > 2:
                    address, gw, name = guest.split(':')
                elif len(guest.split(':')) > 1:
                    address, gw = guest.split(':')
                    name = None
                else:
                    address, gw, name = guest, None, None

                item = O()
                item.specs = O()
                spec = item.specs
                spec.address = IPNetwork(address)
                spec.gw = IPAddress(gw) if gw else None
                spec.cores = self.options.get('cores')
                spec.name = name
            self.guests.append(item)

        if isinstance(self.device, DeviceAccess):
            self.options.admin_username = self.device.get_admin_creds(
            ).username or ADMIN_USERNAME
            self.options.admin_password = self.device.get_admin_creds(
            ).password or ADMIN_PASSWORD

        self.options.setifnone('admin_username', ADMIN_USERNAME)
        self.options.setifnone('admin_password', ADMIN_PASSWORD)

        # Assumed we are using vcmp provisioning here if we are not reverting
        # BIG-IP back to whatever provision.
        if not self.options.revert:
            self.options.provision = 'vcmp'

    def prep(self):
        super(VcmpPlacer, self).prep()
        self.icifc = IcontrolInterface(address=self.address,
                                       username=self.options.admin_username,
                                       password=self.options.admin_password,
                                       port=self.options.ssl_port)

    def get_provider(self, address, csv):
        provider = O()
        if not self.options.no_irack and not csv:
            LOG.info("Using data from iRack")
            provider = self.irack_provider(
                address=self.options.irack_address,
                username=self.options.irack_username,
                apikey=self.options.irack_apikey,
                mgmtip=address,
                timeout=self.options.timeout)
        elif csv:
            LOG.info("Using data from CSV: %s" % csv)
            provider = self.csv_provider(mgmtip=address, csv_rpath=csv)

        return provider

    def wait_reboot(self, icifc, timeout=None):
        timeout = timeout or self.options.timeout

        ICMD.system.IsServiceUp('MCPD', ifc=icifc).\
            run_wait(timeout=timeout,
                     timeout_message="Timeout ({0}s) while waiting for MCPD "
                                     "to come up")
        ICMD.system.IsServiceUp('TMM', ifc=icifc).\
            run_wait(timeout_message="Timeout ({0}s) while waiting for TMM "
                                     "to come up")

        ICMD.management.GetDbvar('Configsync.LocalConfigTime', ifc=icifc).\
            run_wait(lambda x: int(x) > 0,
                     progress_cb=lambda x: 'waiting configsync...',
                     timeout=timeout)

        ICMD.system.FileExists('/var/run/mprov.pid', ifc=self.icifc).\
            run_wait(lambda x: x is False,
                     progress_cb=lambda x: 'mprov still running...',
                     timeout=timeout)
        ICMD.system.FileExists('/var/run/grub.conf.lock', ifc=self.icifc).\
            run_wait(lambda x: x is False,
                     progress_cb=lambda x: 'grub.lock still present...',
                     timeout=timeout)

    def clean_vdisk(self):
        images = SCMD.tmsh.list('vcmp virtual-disk', ifc=self.sshifc)
        for image in images:
            LOG.info("Cleaning old Virtual Disk Image: %s" % image.split()[-1])
            SCMD.tmsh.run(image, command='delete', ifc=self.sshifc)

    def delete_guests(self):
        guests = SCMD.tmsh.list('vcmp guest', ifc=self.sshifc)
        for guest, items in guests.iteritems():
            if 'state' in items and items['state'] in VCMP_ONLINE_STATES:
                LOG.info("Disabling %s..." % guest.split()[-1])
                SCMD.tmsh.run(guest + ' state configured',
                              command='modify',
                              ifc=self.sshifc)
            LOG.info("Deleting %s..." % guest.split()[-1])
            SCMD.tmsh.run(guest, command='delete', ifc=self.sshifc)

    def setup(self):
        ctx = self.make_context()
        if self.options.revert:
            LOG.info("Reverting by provisioning to %s" %
                     self.options.provision)

        if self.options.clean_only and 'vcmp' in ctx.provision.keys():
            # Disable any running vCMP Guests then delete them
            self.delete_guests()
            self.clean_vdisk()
            return

        if not self.guests and not self.revert:
            LOG.warning("No vCMP Guests to setup. Just use the normal "
                        "configurator if you only need to do vcmp "
                        "provisioning only...")
            return

        provider = self.get_provider(self.address, self.options.csv)
        reboot = True

        # TODO: We will need to add more logic here to check if the current
        # running guests are the same as our config. If so, leave it, otherwise
        # clean it out.
        if 'vcmp' in ctx.provision.keys():
            # Disable any running vCMP Guests then delete them
            self.delete_guests()
            self.clean_vdisk()

        if self.options.provision in ctx.provision.keys():
            LOG.info("No need for reboot...")
            reboot = False
        # System
        o = O()
        o.hostname = self.options.hostname or provider.get('hostname')
        self.set_networking(o)
        self.set_provisioning(o)
        if provider.mgmtip and (o.mgmtip.ip != provider.mgmtip.ip
                                or o.mgmtip.cidr != provider.mgmtip.cidr):
            LOG.warning('Management address mismatch. iRack/CSV has {0} but '
                        'found {1}. iRack/CSV will take '
                        'precedence.'.format(provider.mgmtip, o.mgmtip))
            o.mgmtip = provider.mgmtip

        if provider.gateway and o.gateway != provider.gateway:
            LOG.warning('Default gateway address mismatch. iRack/CSV has '
                        '{0} but found {1}. iRack/CSV will take '
                        'precedence.'.format(provider.gateway, o.gateway))
            o.gateway = provider.gateway
        tree = self.SystemConfig(self.context, partitions=0, **o).run()

        # Skip this if we are reverting back to another provision
        if not self.options.revert:
            # vCMP Guests
            LOG.info("Generating vCMP Guests...")

            # Look for image and hotfix with the same version as BIG-IP Host.
            target_version = ctx.version.version
            images = SCMD.ssh.generic('ls /shared/images',
                                      ifc=self.sshifc).stdout
            hotfix = base = None
            for image in images.split():
                if target_version in image and 'Hotfix' in image:
                    hotfix = image
                elif target_version in image:
                    base = image

                if hotfix and image:
                    break

            for i, guest in enumerate(self.guests):
                csv = self.device.specs.csv if isinstance(
                    self.device, DeviceAccess) else self.options.csv

                # Just IP, no netmask info like x.x.x.x/yy
                ip = guest.specs.address.ip if isinstance(
                    guest.specs.address, IPNetwork) else guest.address
                provider = self.get_provider(ip, csv)

                management_ip = provider.mgmtip or IPNetwork(
                    guest.specs.address)
                management_gw = provider.gateway or guest.specs.gw

                if str(management_ip.netmask) == '255.255.255.255':
                    LOG.warning(
                        "Mgmt netmask probably was not set! Defaulting to "
                        "/24 prefix.")
                    management_ip.prefixlen = DEFAULT_NETMASK_PREFIX

                if not management_gw:
                    LOG.warning("Gateway not set!!")
                    default_gw = management_ip.broadcast - 1
                    management_gw = default_gw
                    LOG.warning("Defaulting to %s" % default_gw)

                guest_name = guest.specs.name or GUEST_NAME % (i)
                o = O(tree=tree,
                      name=guest_name,
                      management_ip=management_ip,
                      management_gw=management_gw,
                      initial_image=base,
                      initial_hotfix=hotfix)
                if guest.specs.get('cores'):
                    o.cores_per_slot = guest.specs.get('cores')

                tree = self.vCMPConfig(self.context, **o).run()

        if self.options.stdout:
            self.dump(tree, ctx)
            return

        self.load(tree, ctx)

        # If BIG-IP isn't already provisioned, a reboot will happen.
        timeout = self.options.timeout
        if reboot:
            ic = self.icifc.open()
            uptime = ic.System.SystemInfo.get_uptime()
            LOG.info("Pausing 30 seconds to wait until reboot has happened...")
            time.sleep(30)

            if uptime:
                ICMD.system.HasRebooted(uptime, ifc=self.icifc).\
                    run_wait(timeout=timeout)
                LOG.info('Device is rebooting...')

            LOG.info('Wait for box to be ready...')
            self.wait_reboot(self.icifc)

        self.reset_trust()
        self.ready_wait()

        # Skip this if we are reverting back to another provision
        if not self.options.revert:
            # There shouldn't be any virtual disks so clean out any remaining ones
            # from previous runs
            self.clean_vdisk()

            # Deploy vCMP Guests.
            guests = SCMD.tmsh.list('vcmp guest', ifc=self.sshifc)
            for guest, items in guests.iteritems():
                if 'state' not in items or items['state'] != 'deployed':
                    LOG.info("Deploying %s..." % guest.split()[-1])
                    SCMD.tmsh.run(guest + ' state deployed',
                                  command='modify',
                                  ifc=self.sshifc)

            # Wait until vCMP guests are running
            timeout = VCMP_TIMEOUT * (
                len(self.guests) / 6 + 1
            )  # Only 6 vCMP Guests can start in parallel
            for guest in self.guests:
                try:
                    ip = guest.specs.address.ip if isinstance(
                        guest.specs.address, IPNetwork) else guest.address
                    icifc = IcontrolInterface(address=ip,
                                              username=ADMIN_USERNAME,
                                              password=ADMIN_PASSWORD,
                                              port=self.options.ssl_port)
                    LOG.info('Wait for %s to be ready...' % ip)
                    self.wait_reboot(icifc, timeout=timeout)
                finally:
                    icifc.close()

        self.save(ctx)
        self.ssh_key_exchange()

    def cleanup(self):
        super(VcmpPlacer, self).cleanup()
        self.icifc.close()
Exemple #5
0
    def push_certificate(self, pkey, cert):

        icifc = IcontrolInterface(device=self.options.device,
                                  address=self.address,
                                  username=self.options.admin_username,
                                  password=self.options.admin_password,
                                  port=self.options.ssl_port,
                                  debug=self.options.verbose)
        ic = icifc.open()
        key_pem = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkey)
        cert_pem = crypto.dump_certificate(crypto.FILETYPE_PEM, cert)

        try:
            ic.Management.KeyCertificate.certificate_delete(
                mode='MANAGEMENT_MODE_WEBSERVER', cert_ids=['server'])
            ic.Management.KeyCertificate.key_delete(
                mode='MANAGEMENT_MODE_WEBSERVER', key_ids=['server'])
        except:
            LOG.warning('Exception occurred while deleting cert/key')

        ic.Management.KeyCertificate.certificate_import_from_pem(
            mode='MANAGEMENT_MODE_WEBSERVER',
            cert_ids=['server'],
            pem_data=[cert_pem],
            overwrite=1)

        ic.Management.KeyCertificate.key_import_from_pem(
            mode='MANAGEMENT_MODE_WEBSERVER',
            key_ids=['server'],
            pem_data=[key_pem],
            overwrite=1)

        icifc.close()

        # XXX: Unfortunately we can't reinit httpd through iControl. It's a KI
        # http://devcentral.f5.com/Default.aspx?tabid=53&forumid=1&postid=1170498&view=topic
        #
        # action = pc.System.Services.typefactory.\
        #        create('System.Services.ServiceAction').\
        #        SERVICE_ACTION_REINIT
        # service = pc.System.Services.typefactory.\
        #        create('System.Services.ServiceType').\
        #        SERVICE_HTTPD
        # pc.System.Services.set_service(services = [service], \
        #                               service_action = action)
        # pc.System.Services.get_service_status([service])

        with SSHInterface(device=self.options.device,
                          address=self.address,
                          username=self.options.root_username,
                          password=self.options.root_password,
                          port=self.options.ssh_port) as sshifc:
            version = SCMD.ssh.get_version(ifc=sshifc)
            if version >= 'bigiq 4.4':
                sshifc.api.run('bigstart reinit webd')
            elif version >= 'bigiq 4.3' and version < 'bigiq 4.4':
                sshifc.api.run('bigstart reinit nginx')
            else:
                sshifc.api.run('bigstart reinit httpd')

        return True