def test_13_delete_select_0(): ''' add a CDS and see if no issue occurs if it and "a zeroth" (ghost) CDSs are selected for deletion ''' # for RHBZ#1305612 # choose a random CDS and add it cds = random.choice(CDS_HOSTNAMES) RHUIManagerInstance.add_instance(RHUA, "cds", cds) cds_list = RHUIManagerInstance.list(RHUA, "cds") nose.tools.assert_not_equal(cds_list, []) # try the deletion RHUIManager.screen(RHUA, "cds") Expect.enter(RHUA, "d") Expect.expect(RHUA, "Enter value") Expect.enter(RHUA, "0") Expect.expect(RHUA, "Enter value") Expect.enter(RHUA, "1") Expect.expect(RHUA, "Enter value") Expect.enter(RHUA, "c") state = Expect.expect_list(RHUA, [(re.compile(".*Are you sure.*", re.DOTALL), 1), (re.compile(".*An unexpected error.*", re.DOTALL), 2)]) if state == 1: Expect.enter(RHUA, "y") RHUIManager.quit(RHUA, timeout=180) else: Expect.enter(RHUA, "q") # the CDS list ought to be empty now; if not, delete the CDS and fail cds_list = RHUIManagerInstance.list(RHUA, "cds") if cds_list: RHUIManagerInstance.delete_all(RHUA, "cds") raise AssertionError("The CDS list is not empty after the deletion attempt: %s." % cds_list)
def test_14_verbose_reporting(): ''' check if a failure is reported properly (if puppet is verbose) ''' # for RHBZ#1751378 # choose a random CDS and open port 443 on it, which will later prevent Apache from starting cds = random.choice(CDS) Expect.enter(cds, "ncat -l 443 --keep-open") # try adding the CDS and check for the specific error message in the output error_msg = "change from stopped to running failed" RHUIManager.screen(RHUA, "cds") Expect.enter(RHUA, "a") Expect.expect(RHUA, "Hostname") Expect.enter(RHUA, cds.hostname) Expect.expect(RHUA, "Username") Expect.enter(RHUA, SUDO_USER_NAME) Expect.expect(RHUA, "Absolute") Expect.enter(RHUA, SUDO_USER_KEY) Expect.expect(RHUA, "Proceed") Expect.enter(RHUA, "y") state = Expect.expect_list(RHUA, [(re.compile(".*%s.*" % error_msg, re.DOTALL), 1), (re.compile(".*Aborting.*", re.DOTALL), 2), (re.compile(".*was successfully configured.*", re.DOTALL), 3)], timeout=180) # quit rhui-manager, clean up, fail if the error message didn't appear Expect.enter(RHUA, "q") Expect.enter(cds, CTRL_C) cds_list = RHUIManagerInstance.list(RHUA, "cds") if cds_list: RHUIManagerInstance.delete_all(RHUA, "cds") if state != 1: raise AssertionError("The expected error message was not seen in rhui-manager's output.")
def test_18_repo_select_0(): '''check if no repo is chosen if 0 is entered when adding a repo''' # for RHBZ#1305612 # upload the small cert and try entering 0 when the list of repos is displayed RHUIManagerEntitlements.upload_rh_certificate( RHUA, "/tmp/extra_rhui_files/rhcert_atomic.pem") RHUIManager.screen(RHUA, "repo") Expect.enter(RHUA, "a") Expect.expect(RHUA, "Enter value", 180) Expect.enter(RHUA, "3") Expect.expect(RHUA, "Enter value") Expect.enter(RHUA, "0") Expect.expect(RHUA, "Enter value") Expect.enter(RHUA, "c") Expect.expect(RHUA, "Proceed") Expect.enter(RHUA, "y") Expect.expect(RHUA, "Content") Expect.enter(RHUA, "q") # the RHUI repo list ought to be empty now; if not, delete the repo and fail repo_list = RHUIManagerRepo.list(RHUA) RHUIManager.remove_rh_certs(RHUA) if repo_list: RHUIManagerRepo.delete_all_repos(RHUA) raise AssertionError("The repo list is not empty: %s." % repo_list)
def create_atomic_conf_pkg(connection, dirname, tarname, certpath, certkey, port=""): ''' create an atomic client configuration package (RHEL 7+ only) ''' RHUIManager.screen(connection, "client") Expect.enter(connection, "o") Expect.expect(connection, "Full path to local directory.*:") Expect.enter(connection, dirname) Expect.expect(connection, "Name of the tar file.*:") Expect.enter(connection, tarname) Expect.expect(connection, "Full path to the entitlement certificate.*:") Expect.enter(connection, certpath) Expect.expect(connection, "Full path to the private key.*:") Expect.enter(connection, certkey) Expect.expect(connection, "Port to serve Docker content on .*:") Expect.enter(connection, port) Expect.expect(connection, "Location: %s/%s.tar.gz" % \ (dirname, tarname)) Expect.enter(connection, "q")
def test_01_login_add_cds_hap(): """log in to RHUI, add CDS and HAProxy nodes""" RHUIManager.initial_run(RHUA) for cds in HOSTNAMES["CDS"]: RHUIManagerInstance.add_instance(RHUA, "cds", cds) for haproxy in HOSTNAMES["HAProxy"]: RHUIManagerInstance.add_instance(RHUA, "loadbalancers", haproxy)
def list(connection): ''' return the list of entitlements ''' RHUIManager.screen(connection, "entitlements") lines = RHUIManager.list_lines(connection, prompt=RHUIManagerEntitlements.prompt) return lines
def check_for_package(connection, reponame, package): ''' list packages in a repository ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "p") RHUIManager.select_one(connection, reponame) Expect.expect(connection, "\(blank line for no filter\):") Expect.enter(connection, package) pattern = re.compile('.*only\.\r\n(.*)\r\n-+\r\nrhui\s* \(repo\)\s* =>', re.DOTALL) ret = Expect.match(connection, pattern, grouplist=[1])[0] reslist = map(lambda x: x.strip(), ret.split("\r\n")) packagelist = [] for line in reslist: if line == '': continue if line == 'Packages:': continue if line == 'No packages found that match the given filter.': continue if line == 'No packages in the repository.': continue packagelist.append(line) return packagelist
def create_container_conf_rpm(connection, dirname, rpmname, rpmversion="", rpmrelease="", port=""): ''' create a container client configuration RPM ''' RHUIManager.screen(connection, "client") Expect.enter(connection, "d") Expect.expect(connection, "Full path to local directory.*:") Expect.enter(connection, dirname) Expect.expect(connection, "Name of the RPM:") Expect.enter(connection, rpmname) Expect.expect(connection, "Version of the configuration RPM.*:") Expect.enter(connection, rpmversion) Expect.expect(connection, "Release of the configuration RPM.*:") Expect.enter(connection, rpmrelease) Expect.expect(connection, "Port to serve Docker content on .*:") Expect.enter(connection, port) if not rpmversion: rpmversion = "2.0" if not rpmrelease: rpmrelease = "1" Expect.expect(connection, "Location: %s/%s-%s/build/RPMS/noarch/%s-%s-%s.noarch.rpm" % \ (dirname, rpmname, rpmversion, rpmname, rpmversion, rpmrelease)) Expect.enter(connection, "q")
def upload_rh_certificate(connection, certificate_file="/tmp/extra_rhui_files/rhcert.pem"): ''' upload a new or updated Red Hat content certificate ''' bad_cert_msg = "The provided certificate is expired or invalid" incompatible_cert_msg = "does not contain any entitlements" RHUIManager.screen(connection, "entitlements") Expect.enter(connection, "u") Expect.expect(connection, "Full path to the new content certificate:") Expect.enter(connection, certificate_file) state = Expect.expect_list(connection, [(re.compile(".*The RHUI will be updated.*", re.DOTALL), 1), (re.compile(".*Cannot find file.*", re.DOTALL), 2)]) if state == 2: Expect.enter(connection, CTRL_C) RHUIManager.quit(connection) raise MissingCertificate("No such certificate file: %s" % certificate_file) Expect.enter(connection, "y") match = Expect.match(connection, re.compile("(.*)" + PROMPT, re.DOTALL)) matched_string = match[0].replace('l\r\n\r\nRed Hat Entitlements\r\n\r\n ' + '\x1b[92mValid\x1b[0m\r\n ', '', 1) if bad_cert_msg in matched_string: Expect.enter(connection, 'q') raise BadCertificate() if incompatible_cert_msg in matched_string: Expect.enter(connection, 'q') raise IncompatibleCertificate() entitlements_list = [] pattern = re.compile('(.*?\r\n.*?pem)', re.DOTALL) for entitlement in pattern.findall(matched_string): entitlements_list.append(entitlement.strip()) Expect.enter(connection, 'q') return entitlements_list
def upload_content(connection, repolist, path): ''' upload content to a custom repository ''' # Temporarily quit rhui-manager and check whether "path" is a file or a directory. # If it is a directory, get a list of *.rpm files in it. Expect.enter(connection, 'q') Expect.enter(connection, "stat -c %F " + path) path_type = Expect.expect_list( connection, [(re.compile(".*regular file.*", re.DOTALL), 1), (re.compile(".*directory.*", re.DOTALL), 2)]) if path_type == 1: content = [basename(path)] elif path_type == 2: Expect.enter(connection, "echo " + path + "/*.rpm") output = Expect.match(connection, re.compile("(.*)", re.DOTALL))[0] rpm_files = output.splitlines()[1] content = [] for rpm_file in rpm_files.split(): content.append(basename(rpm_file)) else: # This should not happen. Getting here means that "path" is neither a file nor a directory. # Anyway, going on with no content, leaving it up to proceed_with_check() to handle this situation. content = [] # Start rhui-manager again and continue. RHUIManager.initial_run(connection) RHUIManager.screen(connection, "repo") Expect.enter(connection, "u") RHUIManager.select(connection, repolist) Expect.expect(connection, "will be uploaded:") Expect.enter(connection, path) RHUIManager.proceed_with_check(connection, "The following RPMs will be uploaded:", content) RHUIManager.quit(connection)
def check_for_package(connection, reponame, package): ''' list packages in a repository ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "p") RHUIManager.select_one(connection, reponame) Expect.expect(connection, r"\(blank line for no filter\):") Expect.enter(connection, package) pattern = re.compile(r'.*only\.\r\n(.*)\r\n-+\r\nrhui\s* \(repo\)\s* =>', re.DOTALL) ret = Expect.match(connection, pattern, grouplist=[1])[0] reslist = map(str.strip, str(ret).splitlines()) packagelist = [] for line in reslist: if line == '': continue if line == 'Packages:': continue if line == 'No packages found that match the given filter.': continue if line == 'No packages in the repository.': continue packagelist.append(line) Expect.enter(connection, 'q') return packagelist
def list(connection): ''' return the list of entitlements ''' RHUIManager.screen(connection, "entitlements") lines = RHUIManager.list_lines(connection, prompt=PROMPT) Expect.enter(connection, 'q') return lines
def test_01_setup(self): '''log in to rhui-manager, upload RH cert, add a repo to sync ''' RHUIManager.initial_run(RHUA) entlist = RHUIManagerEntitlements.upload_rh_certificate(RHUA) nose.tools.assert_not_equal(len(entlist), 0) RHUIManagerRepo.add_rh_repo_by_repo(RHUA, [ Util.format_repo(self.yum_repo_name, self.yum_repo_version, self.yum_repo_kind) ])
def list(connection): ''' return the list of currently managed HAPs ''' RHUIManager.screen(connection, "loadbalancers") # eating prompt!! lines = RHUIManager.list_lines(connection, prompt=RHUIManagerHap.prompt) ret = Hap.parse(lines) return [hap for _, hap in ret]
def delete_haps(connection, *hapes): ''' unregister (delete) HAP instance from the RHUI ''' RHUIManager.screen(connection, "loadbalancers") Expect.enter(connection, "d") RHUIManager.select_items(connection, *hapes) Expect.enter(connection, "y") Expect.expect(connection, "Unregistered" + ".*rhui \(.*\) =>", 180)
def list(connection): ''' return the list of currently managed CDSes ''' RHUIManager.screen(connection, "cds") # eating prompt!! lines = RHUIManager.list_lines(connection, prompt=RHUIManagerCds.prompt) ret = Cds.parse(lines) return [cds for _, cds in ret]
def delete_cdses(connection, *cdses): ''' unregister (delete) CDS instance from the RHUI ''' RHUIManager.screen(connection, "cds") Expect.enter(connection, "d") RHUIManager.select_items(connection, *cdses) Expect.enter(connection, "y") Expect.expect(connection, "Unregistered" + ".*rhui \(.*\) =>", 180)
def add_rh_repo_all(connection): ''' add a new Red Hat content repository (All in Certificate) ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "a") Expect.expect(connection, "Import Repositories:.*to abort:", 660) Expect.enter(connection, "1") RHUIManager.proceed_without_check(connection) Expect.expect(connection, ".*rhui \(" + "repo" + "\) =>", 180)
def test_00_rhui_init(): ''' add a CDS and run rhui-subscription-sync to ensure their log files exist ''' # use initial_run first to ensure we're logged in to rhui-manager RHUIManager.initial_run(CONNECTION_RHUA) RHUIManagerInstance.add_instance(CONNECTION_RHUA, "cds") # can't use expect_retval as the exit code can be 0 or 1 (sync is configured or unconfigured) Expect.ping_pong(CONNECTION_RHUA, "rhui-subscription-sync ; echo ACK", "ACK")
def list(connection): ''' return the list of currently managed CDSes ''' RHUIManager.screen(connection, "cds") # eating prompt!! lines = RHUIManager.list_lines(connection, prompt=RHUIManagerCds.prompt) ret = Cds.parse(lines) # custom quitting; have eaten the prompt Expect.enter(connection, 'q') return [cds for _, cds in ret]
def test_99_cleanup(self): '''clean up''' Expect.expect_retval(CLI, "rhui-set-release --unset") Util.remove_rpm(CLI, [self.test_package, CONF_RPM_NAME]) RHUIManagerCLI.repo_delete(RHUA, self.repo_id) Expect.expect_retval(RHUA, "rm -rf /tmp/%s*" % CONF_RPM_NAME) if not getenv("RHUISKIPSETUP"): RHUIManager.remove_rh_certs(RHUA) RHUICLI.delete(RHUA, "haproxy", force=True) RHUICLI.delete(RHUA, "cds", force=True) ConMgr.remove_ssh_keys(RHUA)
def list(connection, screen): ''' return the list of currently managed CDSes ''' RHUIManager.screen(connection, screen) # eating prompt!! lines = RHUIManager.list_lines(connection, "rhui \(" + screen + "\) => ") ret = Instance.parse(lines) Expect.enter(connection, 'q') return [cds for _, cds in ret]
def delete_all_repos(connection): ''' delete all repositories from the RHUI ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "d") Expect.expect(connection, "Enter value .*:", 360) Expect.enter(connection, "a") Expect.expect(connection, "Enter value .*:") Expect.enter(connection, "c") RHUIManager.proceed_without_check(connection) Expect.expect(connection, ".*rhui \(" + "repo" + "\) =>", 360)
def test_99_cleanup(): '''Cleanup: Delete all repositories from RHUI (interactively; not currently supported by the CLI), remove certs and other files''' RHUIManagerRepo.delete_all_repos(CONNECTION) nose.tools.assert_equal(RHUIManagerRepo.list(CONNECTION), []) RHUIManager.remove_rh_certs(CONNECTION) Expect.ping_pong(CONNECTION, "rm -rf /tmp/atomic_and_my* ; " + "ls /tmp/atomic_and_my* 2>&1", "No such file or directory") Expect.ping_pong(CONNECTION, "rm -f /tmp/repos.std{out,err} ; " + "ls /tmp/repos.std{out,err} 2>&1", "No such file or directory") rmtree(TMPDIR)
def _sync_cds(self, cdslist): """ Sync cds """ if (not "RHUA" in self.rs.Instances.keys()) or len(self.rs.Instances["RHUA"]) < 1: raise nose.exc.SkipTest("can't test without RHUA!") try: RHUIManagerSync.sync_cds(self.rs.Instances["RHUA"][0], cdslist) except ExpectFailed: # The CDS is not available for syncing so most probably it's syncing right now # Trying to check the status Expect.enter(self.rs.Instances["RHUA"][0], "b") RHUIManager.quit(self.rs.Instances["RHUA"][0]) self._sync_wait_cds(cdslist)
def add_instance(connection, screen, hostname, user_name="ec2-user", ssh_key_path="/root/.ssh/id_rsa_rhua", update=False): ''' Register (add) a new CDS or HAProxy instance @param hostname instance @param update: Bool; update the cds or hap if it is already tracked or raise ExpectFailed ''' RHUIManager.screen(connection, screen) Expect.enter(connection, "a") Expect.expect(connection, ".*Hostname of the .*instance to register:") Expect.enter(connection, hostname) state = Expect.expect_list(connection, [ \ (re.compile(".*Username with SSH access to %s and sudo privileges:.*" % hostname, re.DOTALL), 1), (re.compile(".*instance with that hostname exists.*Continue\?\s+\(y/n\): ", re.DOTALL), 2) ]) if state == 2: # cds or haproxy of the same hostname is already being tracked if not update: # but we don't wish to update its config: raise raise ExpectFailed( "%s already tracked but update wasn't required" % hostname) else: # we wish to update, send 'y' answer Expect.enter(connection, "y") # the question about user name comes now Expect.expect( connection, "Username with SSH access to %s and sudo privileges:" % hostname) # if the execution reaches here, uesername question was already asked Expect.enter(connection, user_name) Expect.expect( connection, "Absolute path to an SSH private key to log into %s as ec2-user:"******".*Cannot find file, please enter a valid path.*", re.DOTALL), 1), (PROCEED_PATTERN, 2)]) if state == 1: # don't know how to continue with invalid path: raise Expect.enter(connection, CTRL_C) Expect.enter(connection, "q") raise InvalidSshKeyPath(ssh_key_path) # all OK, confirm Expect.enter(connection, "y") # some installation and configuration through Puppet happens here, let it take its time RHUIManager.quit(connection, "The .*was successfully configured.", 180)
def check_detailed_information(connection, repo_data, type_data, gpg_data, package_count): ''' verify that a repository has the expected properties repo_data: [string, string] [0]: repo name [1]: relative path type_data: [bool, bool] [0]: True? Custom. False? Red Hat. [1]: True? Protected. False? Unprotected. (Only checked with a Custom repo.) gpg_data: [bool, string, bool] [0]: True? GPG Check Yes. False? GPG Check No. [1]: Custom GPG Keys (comma-separated names), or None. [2]: True? Red Hat GPG Key Yes. False? Red Hat GPG Key No. ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "i") RHUIManager.select(connection, [repo_data[0]]) pattern = re.compile(r".*(Name:.*)\r\n\r\n-+\r\nrhui\s* \(repo\)\s* =>", re.DOTALL) actual_responses = Expect.match(connection, pattern)[0].splitlines() Expect.enter(connection, "q") expected_responses = ["Name: " + repo_data[0]] if type_data[0]: repo_type = "Custom" if type_data[1]: relative_path = "protected/" + repo_data[1] else: relative_path = "unprotected/" + repo_data[1] else: repo_type = "Red Hat" relative_path = repo_data[1] expected_responses.append("Type: " + repo_type) expected_responses.append("Relative Path: " + relative_path) if gpg_data[0]: expected_responses.append("GPG Check: Yes") if gpg_data[1]: expected_responses.append("Custom GPG Keys: " + gpg_data[1]) else: expected_responses.append("Custom GPG Keys: (None)") if gpg_data[2]: expected_responses.append("Red Hat GPG Key: Yes") else: expected_responses.append("Red Hat GPG Key: No") else: expected_responses.append("GPG Check: No") expected_responses.append("Package Count: " + str(package_count)) if repo_type == "Red Hat": sync_data = actual_responses.pop() nose.tools.ok_("Next Sync:" in sync_data) sync_data = actual_responses.pop() nose.tools.ok_("Last Sync:" in sync_data) nose.tools.eq_(actual_responses, expected_responses)
def delete_all(connection, screen): ''' unregister (delete) all CDS or HAProxy instances from the RHUI ''' RHUIManager.screen(connection, screen) Expect.enter(connection, "d") Expect.expect(connection, "Enter value .*:") Expect.enter(connection, "a") Expect.expect(connection, "Enter value .*:") Expect.enter(connection, "c") Expect.expect(connection, "Are you sure .*:") Expect.enter(connection, "y") RHUIManager.quit(connection, "Unregistered")
def upload_content(connection, repolist, path): ''' upload content to a custom repository ''' # Temporarily quit rhui-manager and check whether "path" is a file or a directory. # If it is a directory, get a list of *.rpm files in it. Expect.enter(connection, 'q') Expect.enter(connection, "stat -c %F " + path) path_type = Expect.expect_list(connection, [(re.compile(".*regular file.*", re.DOTALL), 1), (re.compile(".*directory.*", re.DOTALL), 2)]) if path_type == 1: content = [basename(path)] elif path_type == 2: Expect.enter(connection, "echo " + path + "/*.rpm") output = Expect.match(connection, re.compile("(.*)", re.DOTALL))[0] rpm_files = output.splitlines()[1] content = [] for rpm_file in rpm_files.split(): content.append(basename(rpm_file)) else: # This should not happen. Getting here means that "path" is neither a file nor a directory. # Anyway, going on with no content, leaving it up to proceed_with_check() to handle this situation. content = [] # Start rhui-manager again and continue. RHUIManager.initial_run(connection) RHUIManager.screen(connection, "repo") Expect.enter(connection, "u") RHUIManager.select(connection, repolist) Expect.expect(connection, "will be uploaded:") Expect.enter(connection, path) RHUIManager.proceed_with_check(connection, "The following RPMs will be uploaded:", content) Expect.expect(connection, "rhui \(" + "repo" + "\) =>")
def get_cds_status(connection, cdsname): ''' display CDS sync summary ''' RHUIManager.screen(connection, "sync") Expect.enter(connection, "dc") res_list = Expect.match(connection, re.compile(".*\n" + cdsname.replace(".", "\.") + "[\.\s]*\[([^\n]*)\].*" + cdsname.replace(".", "\.") + "\s*\r\n([^\n]*)\r\n", re.DOTALL), [1, 2], 60) connection.cli.exec_command("killall -s SIGINT rhui-manager") ret_list = [] for val in [res_list[0]] + res_list[1].split(" "): val = Util.uncolorify(val.strip()) ret_list.append(val) RHUIManager.quit(connection) return ret_list
def upload_content(connection, repolist, path): ''' upload content to a custom repository ''' # Check whether "path" is a file or a directory. # If it is a directory, get a list of *.rpm files in it. path_type = Util.get_file_type(connection, path) if path_type == "regular file": content = [basename(path)] elif path_type == "directory": content = Util.get_rpms_in_dir(connection, path) else: # This should not happen. Getting here means that "path" is neither a file # nor a directory. # Anyway, going on with no content, # leaving it up to proceed_with_check() to handle this situation. content = [] # Continue in rhui-manager. RHUIManager.screen(connection, "repo") Expect.enter(connection, "u") RHUIManager.select(connection, repolist) Expect.expect(connection, "will be uploaded:") Expect.enter(connection, path) RHUIManager.proceed_with_check(connection, "The following RPMs will be uploaded:", content) RHUIManager.quit(connection, timeout=60)
def get_repo_status(connection, reponame): ''' display repo sync summary ''' RHUIManager.screen(connection, "sync") Expect.enter(connection, "dr") reponame_quoted = reponame.replace(".", "\.") res = Expect.match(connection, re.compile(".*" + reponame_quoted + "\s*\r\n([^\n]*)\r\n.*", re.DOTALL), [1], 60)[0] connection.cli.exec_command("killall -s SIGINT rhui-manager") res = Util.uncolorify(res) ret_list = res.split(" ") for i in range(len(ret_list)): ret_list[i] = ret_list[i].strip() RHUIManager.quit(connection) return ret_list
def create_docker_conf_rpm(connection, dirname, rpmname, rpmversion="", dockerport=""): """ create a client configuration RPM from an entitlement certificate """ RHUIManager.screen(connection, "client") Expect.enter(connection, "d") Expect.expect(connection, "Full path to local directory.*:") Expect.enter(connection, dirname) Expect.expect(connection, "Name of the RPM:") Expect.enter(connection, rpmname) Expect.expect(connection, "Version of the configuration RPM.*:") Expect.enter(connection, rpmversion) Expect.expect(connection, "Port to serve Docker content on .*:") Expect.enter(connection, dockerport) Expect.expect(connection, ".*rhui \(" + "client" + "\) =>")
def test_17_missing_cert_handling(): '''check if rhui-manager can handle the loss of the RH cert''' # for RHBZ#1325390 RHUIManagerEntitlements.upload_rh_certificate(RHUA) # launch rhui-manager in one connection, delete the cert in the other RHUIManager.screen(RHUA, "repo") RHUIManager.remove_rh_certs(RHUA_2) Expect.enter(RHUA, "a") # a bit strange response to see in this context, but eh, no == all if you're a geek Expect.expect( RHUA, "All entitled products are currently deployed in the RHUI") Expect.enter(RHUA, "q") # an error message should be logged, though Expect.ping_pong(RHUA, "tail /root/.rhui/rhui.log", "The entitlement.*has no associated certificate")
def test_99_cleanup(self): '''cleanup: remove repos and temporary files''' RHUIManagerCLI.repo_delete(RHUA, self.product["id"]) RHUIManager.remove_rh_certs(RHUA) Expect.ping_pong( RHUA, "rm -rf /tmp/%s* ; " % CLI_CFG[0] + "ls /tmp/%s* 2>&1" % CLI_CFG[0], "No such file or directory") Expect.ping_pong( RHUA, "rm -f /tmp/repos.std{out,err} ; " + "ls /tmp/repos.std{out,err} 2>&1", "No such file or directory") Expect.ping_pong( RHUA, "rm -rf /tmp/%s* ; " % ALT_CONTENT_SRC_NAME + "ls /tmp/%s* 2>&1" % ALT_CONTENT_SRC_NAME, "No such file or directory") rmtree(TMPDIR)
def list_custom_entitlements(connection): ''' list custom entitlements ''' RHUIManager.screen(connection, "entitlements") Expect.enter(connection, "c") match = Expect.match(connection, re.compile("c\r\n\r\nCustom Repository Entitlements\r\n\r\n(.*)" + RHUIManagerEntitlements.prompt, re.DOTALL))[0] repo_list = [] for line in match.splitlines(): if "Name:" in line: repo_list.append(line.replace("Name:", "").strip()) return sorted(repo_list)
def test_01_setup(): """log in to RHUI, ensure CDS & HAProxy nodes have been added""" if not getenv("RHUISKIPSETUP"): RHUIManager.initial_run(RHUA) RHUICLI.add(RHUA, "cds", unsafe=True) RHUICLI.add(RHUA, "haproxy", unsafe=True) # check that cds_list = RHUICLI.list(RHUA, "cds") nose.tools.ok_(cds_list) hap_list = RHUICLI.list(RHUA, "haproxy") nose.tools.ok_(hap_list) # if running RHEL Beta, temporarily restore the non-Beta repos potentially disabled by choose_repo.py cmd = "if grep -q Beta /etc/redhat-release; then " \ "cp /etc/yum.repos.d/redhat-rhui.repo{.disabled,}; " \ "yum-config-manager --enable %s %s; fi" % (BIG_REPO, EMP_REPO) Expect.expect_retval(RHUA, cmd)
def list_rh_entitlements(connection): ''' list Red Hat entitlements ''' RHUIManager.screen(connection, "entitlements") Expect.enter(connection, "l") match = Expect.match(connection, re.compile("(.*)" + RHUIManagerEntitlements.prompt, re.DOTALL)) matched_string = match[0].replace('l\r\n\r\nRed Hat Entitlements\r\n\r\n \x1b[92mValid\x1b[0m\r\n ', '', 1) entitlements_list = [] pattern = re.compile('(.*?\r\n.*?pem)', re.DOTALL) for entitlement in pattern.findall(matched_string): entitlements_list.append(entitlement.strip()) return entitlements_list
def delete_repo(connection, repolist): ''' delete a repository from the RHUI ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "d") RHUIManager.select(connection, repolist) RHUIManager.proceed_without_check(connection) RHUIManager.quit(connection)
def sync_cluster(connection, clusterlist): ''' sync a CDS cluster immediately ''' RHUIManager.screen(connection, "sync") Expect.enter(connection, "sl") RHUIManager.select(connection, clusterlist) RHUIManager.proceed_with_check(connection, "The following CDS clusters will be scheduled for synchronization:", clusterlist) RHUIManager.quit(connection)
def sync_cds(connection, cdslist): ''' sync an individual CDS immediately ''' RHUIManager.screen(connection, "sync") Expect.enter(connection, "sc") RHUIManager.select(connection, cdslist) RHUIManager.proceed_with_check(connection, "The following CDS instances will be scheduled for synchronization:", cdslist) RHUIManager.quit(connection)
def test_99_cleanup(self): ''' remove the repo and RH cert, uninstall CDS and HAProxy, delete the ostree configuration ''' RHUIManagerRepo.delete_all_repos(RHUA) nose.tools.assert_equal(RHUIManagerRepo.list(RHUA), []) RHUIManagerInstance.delete_all(RHUA, "loadbalancers") RHUIManagerInstance.delete_all(RHUA, "cds") Expect.expect_retval(RHUA, "rm -f /root/test_atomic_ent_cli*") Expect.expect_retval(RHUA, "rm -f /root/test_atomic_pkg.tar.gz") RHUIManager.remove_rh_certs(RHUA) if AH_EXISTS: Expect.expect_retval( ATOMIC_CLI, "ostree remote delete %s" % self.atomic_repo_remote) Expect.expect_retval( ATOMIC_CLI, "mv -f /etc/containers/registries.conf{.backup,}")
def _sync_repo(self, repolist): """ Sync repo """ if (not "RHUA" in self.rs.Instances.keys()) or len(self.rs.Instances["RHUA"]) < 1: raise nose.exc.SkipTest("can't test without RHUA!") try: RHUIManagerSync.sync_repo(self.rs.Instances["RHUA"][0], repolist) except ExpectFailed: # The repo is not available for syncing so most probably it's syncing right now # Trying to check the status Expect.enter(self.rs.Instances["RHUA"][0], "b") RHUIManager.quit(self.rs.Instances["RHUA"][0]) for repo in repolist: reposync = ["In Progress", "", ""] while reposync[0] in ["In Progress", "Never"]: time.sleep(10) reposync = RHUIManagerSync.get_repo_status(self.rs.Instances["RHUA"][0], repo) nose.tools.assert_equal(reposync[2], "Success")
def add_docker_container(connection, containername, containerid="", displayname=""): ''' add a new Red Hat docker container ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "ad") Expect.expect(connection, "Name of the container in the registry:") Expect.enter(connection, containername) Expect.expect(connection, "Unique ID for the container .*]", 60) Expect.enter(connection, containerid) Expect.expect(connection, "Display name for the container.*]:") Expect.enter(connection, displayname) RHUIManager.proceed_with_check(connection, "The following container will be added:", ["Container Id: " + containername.replace("/","_").replace(".","_"), "Display Name: " + displayname, "Upstream Container Name: " + containername]) Expect.expect(connection, ".*rhui \(" + "repo" + "\) =>")
def test_99_cleanup(self): ''' remove repos, certs, cli rpms; remove rpms from cli, uninstall cds, hap ''' test_rpm_name = self.custom_rpm.rsplit('-', 2)[0] RHUIManagerRepo.delete_all_repos(RHUA) nose.tools.assert_equal(RHUIManagerRepo.list(RHUA), []) Expect.expect_retval(RHUA, "rm -f /root/test_ent_cli*") Expect.expect_retval(RHUA, "rm -rf /root/test_cli_rpm-3.0/") Util.remove_rpm(CLI, [self.test_package, "test_cli_rpm", test_rpm_name]) rmtree(TMPDIR) Helpers.del_legacy_ca(CDS, LEGACY_CA_FILE) if not getenv("RHUISKIPSETUP"): RHUIManagerInstance.delete_all(RHUA, "loadbalancers") RHUIManagerInstance.delete_all(RHUA, "cds") RHUIManager.remove_rh_certs(RHUA)
def list_custom_entitlements(connection): ''' list custom entitlements ''' RHUIManager.screen(connection, "entitlements") Expect.enter(connection, "c") match = Expect.match(connection, re.compile("c\r\n\r\nCustom Repository Entitlements\r\n\r\n(.*)" + PROMPT, re.DOTALL))[0] repo_list = [] for line in match.splitlines(): if "Name:" in line: repo_list.append(line.replace("Name:", "").strip()) Expect.enter(connection, 'q') return sorted(repo_list)
def sync_repo(connection, repolist): ''' sync an individual repository immediately ''' RHUIManager.screen(connection, "sync") Expect.enter(connection, "sr") Expect.expect(connection, "Select one or more repositories.*for more commands:", 60) Expect.enter(connection, "l") RHUIManager.select(connection, repolist) RHUIManager.proceed_with_check(connection, "The following repositories will be scheduled for synchronization:", repolist) RHUIManager.quit(connection)
def subscriptions_unregister(connection, names): ''' unregister a Red Hat subscription from RHUI ''' RHUIManager.screen(connection, "subscriptions") Expect.enter(connection, "d") RHUIManager.select(connection, names) RHUIManager.proceed_with_check(connection, "The following subscriptions will be unregistered:", names) RHUIManager.quit(connection)
def _get_repo_status(connection, reponame): ''' display repo sync summary ''' RHUIManager.screen(connection, "sync") Expect.enter(connection, "dr") res = Expect.match( connection, re.compile(r".*%s\s*\r\n([^\n]*)\r\n.*" % re.escape(reponame), re.DOTALL), [1], 60)[0] connection.cli.exec_command("killall -s SIGINT rhui-manager") res = Util.uncolorify(res) ret_list = res.split(" ") for i, _ in enumerate(ret_list): ret_list[i] = ret_list[i].strip() Expect.enter(connection, CTRL_C) Expect.enter(connection, "q") return ret_list
def list_rh_entitlements(connection): ''' list Red Hat entitlements ''' RHUIManager.screen(connection, "entitlements") Expect.enter(connection, "l") match = Expect.match(connection, re.compile("(.*)" + PROMPT, re.DOTALL)) matched_string = match[0].replace('l\r\n\r\nRed Hat Entitlements\r\n\r\n ' + '\x1b[92mValid\x1b[0m\r\n ', '', 1) entitlements_list = [] pattern = re.compile('(.*?\r\n.*?pem)', re.DOTALL) for entitlement in pattern.findall(matched_string): entitlements_list.append(entitlement.strip()) Expect.enter(connection, 'q') return entitlements_list
def create_conf_rpm(connection, dirname, certpath, certkey, rpmname, rpmversion="", unprotected_repos=None): """ create a client configuration RPM from an entitlement certificate """ RHUIManager.screen(connection, "client") Expect.enter(connection, "c") Expect.expect(connection, "Full path to local directory.*:") Expect.enter(connection, dirname) Expect.expect(connection, "Name of the RPM:") Expect.enter(connection, rpmname) Expect.expect(connection, "Version of the configuration RPM.*:") Expect.enter(connection, rpmversion) Expect.expect(connection, "Full path to the entitlement certificate.*:") Expect.enter(connection, certpath) Expect.expect(connection, "Full path to the private key for the above entitlement certificate:") Expect.enter(connection, certkey) if unprotected_repos: RHUIManager.select(connection, unprotected_repos) Expect.expect(connection, ".*rhui \(" + "client" + "\) =>")
def add_hap(connection, hap=Hap(), update=False): ''' Register (add) a new HAP instance @param hap: rhuilib.hap.Hap instance @param update: Bool; update the hap if it is already tracked or raise ExpectFailed ''' RHUIManager.screen(connection, "loadbalancers") Expect.enter(connection, "a") Expect.expect(connection, ".*Hostname of the HAProxy Load-balancer instance to register:") Expect.enter(connection, hap.host_name) state = Expect.expect_list(connection, [ \ (re.compile(".*Username with SSH access to %s and sudo privileges:.*" % hap.host_name, re.DOTALL), 1), (re.compile(".*A HAProxy Load-balancer instance with that hostname exists.*Continue\?\s+\(y/n\): ", re.DOTALL), 2) ]) if state == 2: # hap of the same hostname is already being tracked if not update: # but we don't wish to update its config: raise raise ExpectFailed("%s already tracked but update wasn't required" % hap.host_name) else: # we wish to update, send 'y' answer Expect.enter(connection, "y") # the question about user name comes now Expect.expect(connection, "Username with SSH access to %s and sudo privileges:" % hap.host_name) # if the execution reaches here, uesername question was already asked Expect.enter(connection, hap.user_name) Expect.expect(connection, "Absolute path to an SSH private key to log into %s as %s:" % (hap.host_name, hap.user_name)) Expect.enter(connection, hap.ssh_key_path) state = Expect.expect_list(connection, [ (re.compile(".*Cannot find file, please enter a valid path.*", re.DOTALL), 1), (PROCEED_PATTERN, 2) ]) if state == 1: # don't know how to continue with invalid path: raise Expect.enter(connection, CTRL_C) Expect.enter(connection, "q") raise InvalidSshKeyPath(hap.ssh_key_path) # all OK, confirm Expect.enter(connection, "y") # some installation and configuration through Puppet happens here, let it take its time Expect.expect(connection, "The HAProxy Load-balancer was successfully configured." + ".*rhui \(.*\) =>", 180)
def add_cds(connection, cds=Cds(), update=False): ''' Register (add) a new CDS instance @param cds: rhuilib.cds.Cds instance @param update: Bool; update the cds if it is already tracked or rise ExpectFailed ''' RHUIManager.screen(connection, "cds") Expect.enter(connection, "a") Expect.expect(connection, "Hostname of the Content Delivery Server instance to register:") Expect.enter(connection, cds.host_name) state = Expect.expect_list(connection, [ \ (re.compile(".*Username with SSH access to %s and sudo privileges:.*" % cds.host_name, re.DOTALL), 1), (re.compile(".*A Content Delivery Server instance with that hostname exists.*Continue\?\s+\(y/n\): ", re.DOTALL), 2) ]) if state == 2: # cds of the same hostname is already being tracked if not update: # but we don't wish to update its config: raise raise ExpectFailed("%s already tracked but update wasn't required" % cds.host_name) else: # we wish to update, send 'y' answer Expect.enter(connection, "y") # the question about user name comes now Expect.expect(connection, "Username with SSH access to %s and sudo privileges:" % cds.host_name) # if the execution reaches here, uesername question was already asked Expect.enter(connection, cds.user_name) Expect.expect(connection, "Absolute path to an SSH private key to log into %s as ec2-user:"******".*Cannot find file, please enter a valid path.*", re.DOTALL), 1), (PROCEED_PATTERN, 2) ]) if state == 1: # don't know how to continue with invalid path: raise Expect.enter(connection, CTRL_C) Expect.enter(connection, "q") raise InvalidSshKeyPath(cds.ssh_key_path) # all OK, confirm Expect.enter(connection, "y") # some installation and configuration through Puppet happens here, let it take its time RHUIManager.quit(connection, "The Content Delivery Server was successfully configured.", timeout=180)
def delete_cdses(connection, *cdses): ''' unregister (delete) CDS instance from the RHUI ''' RHUIManager.screen(connection, "cds") Expect.enter(connection, "d") RHUIManager.select_items(connection, *cdses) RHUIManager.quit(connection, timeout=30)
def upload_rh_certificate(connection): ''' upload a new or updated Red Hat content certificate ''' certificate_file = '/tmp/extra_rhui_files/rhcert.pem' if connection.recv_exit_status("ls -la %s" % certificate_file)!=0: raise ExpectFailed("Missing certificate file: %s" % certificate_file) RHUIManager.screen(connection, "entitlements") Expect.enter(connection, "u") Expect.expect(connection, "Full path to the new content certificate:") Expect.enter(connection, certificate_file) Expect.expect(connection, "The RHUI will be updated with the following certificate:") Expect.enter(connection, "y") match = Expect.match(connection, re.compile("(.*)" + RHUIManagerEntitlements.prompt, re.DOTALL)) matched_string = match[0].replace('l\r\n\r\nRed Hat Entitlements\r\n\r\n \x1b[92mValid\x1b[0m\r\n ', '', 1) entitlements_list = [] pattern = re.compile('(.*?\r\n.*?pem)', re.DOTALL) for entitlement in pattern.findall(matched_string): entitlements_list.append(entitlement.strip()) return entitlements_list
def delete_repo(connection, repolist): ''' delete a repository from the RHUI ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "d") RHUIManager.select(connection, repolist) RHUIManager.proceed_without_check(connection) Expect.expect(connection, ".*rhui \(" + "repo" + "\) =>")
def list(connection): ''' list repositories ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "l") # eating prompt!! pattern = re.compile('l\r\n(.*)\r\n-+\r\nrhui\s* \(repo\)\s* =>', re.DOTALL) ret = Expect.match(connection, pattern, grouplist=[1])[0] reslist = map(lambda x: x.strip(), ret.split("\r\n")) repolist = [] for line in reslist: # Readling lines and searching for repos if line == '': continue if "Custom Repositories" in line: continue if "Red Hat Repositories" in line: continue if "No repositories are currently managed by the RHUI" in line: continue repolist.append(line) return repolist
def add_rh_repo_by_product(connection, productlist): ''' add a new Red Hat content repository (By Product) ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "a") Expect.expect(connection, "Import Repositories:.*to abort:", 660) Expect.enter(connection, "2") RHUIManager.select(connection, productlist) RHUIManager.proceed_with_check(connection, "The following products will be deployed:", productlist) Expect.expect(connection, ".*rhui \(" + "repo" + "\) =>")
def add_rh_repo_by_repo(connection, repolist): ''' add a new Red Hat content repository (By Repository) ''' RHUIManager.screen(connection, "repo") Expect.enter(connection, "a") Expect.expect(connection, "Import Repositories:.*to abort:", 660) Expect.enter(connection, "3") RHUIManager.select(connection, repolist) repolist_mod = list(repolist) for repo in repolist: repolist_mod.append(re.sub(" \\\\\([a-zA-Z0-9_-]*\\\\\) \\\\\(Yum\\\\\)", "", repo)) RHUIManager.proceed_with_check(connection, "The following product repositories will be deployed:", repolist_mod) Expect.expect(connection, ".*rhui \(" + "repo" + "\) =>")